Teknologian jakaminen

C-kokeen kysymykset

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Muuttuvan osion hallintaratkaisu

  • Paras sopeutuminen: vapaa alue kasvaa kapasiteetilla
  • Huonoin sopeutuminen: vapaa alue pienenee kapasiteetin mukaan
  • Mukaudu ensin: vapaata aluetta lisätään osoitteen mukaan

C++-rakenteissa on konstruktoreita.

Luo uusi käyttäjä tai ryhmä Linuxissa

  • useradd: komentoa käytetään käyttäjätilin luomiseen
  • usermod: muokkaa käyttäjätiliä
  • groupadd: Luo uusi työryhmä
  • userdel: poista käyttäjätili

#include voi näkyä ohjelmatiedoston keskellä.

Muodolliset parametrien nimet voidaan jättää pois funktiomäärittelyistä, mutta ei määritelmistä.

lineaarinen taulukko

Ei-tyhjä tietorakenne, jos se täyttää seuraavat kaksi ehtoa:

  1. On vain yksi juurisolmu
  2. Jokaisella solmulla on enintään yksi edellinen solmu ja enintään yksi seuraava solmu.

Sitä kutsutaan lineaariseksi rakenteeksi ja sitä kutsutaan lineaariseksi taulukoksi tietorakenteissa.
Kaksoislinkitetyssä luettelosolmussa on kaksi osoitinkenttää ja se on lineaarinen rakenne.
Kaikkien pyöreän linkitetyn luettelon solmujen osoittimet eivät ole nolla-arvoja, ja ne ovat myös lineaarisia rakenteita.

Etsi hash-taulukko

Hajautustaulukon rakentamismenetelmiä ovat: suoraosoitemenetelmä, jako- ja jakojäännösmenetelmä.

Konfliktinratkaisumenetelmiä ovat:

  • Ketjuosoitemenetelmä: Yhdistä elementit, joilla on sama hash-arvo linkitetyn luettelon avulla.
  • Lineaarinen tunnistus ja sitten hajautusmenetelmä: ristiriidan jälkeen selaa alaspäin löytääksesi tyhjiä paikkoja sijoittelua varten.

Numeeristen alueiden bittikohtainen JA

Kun annetaan kaksi kokonaislukua vasemmalle ja oikealle, jotka edustavat väliä [vasen, oikea], palauta kaikkien tämän välin lukujen bittikohtaisen JA-arvon tulos.

Bittisarjalle, niin kauan kuin on bitti, jonka arvo on nolla, tämän sarjan bittikohtaisen JA-operaation tulos on nolla.

Lisää kuvan kuvaus tähän
Yllä olevasta esimerkistä voimme löytää senKaikille numeroille suoritetun bittikohtaisen JA-operaation tulos on kaikkien vastaavien binäärijonojen yhteinen etuliite ja loput bitit on täytetty nolilla.

Numerot, jotka näkyvät vain kerran (2)

Kun annetaan kokonaislukutaulukon numerot, jokainen elementti näkyy kolme kertaa paitsi elementti, joka esiintyy vain kerran. Etsi ja palauta elementti, joka esiintyy vain kerran.

Suunnittele algoritmi, jolla on lineaarinen aikamonimutkaisuus ja käytä vakiotilaa ongelman ratkaisemiseen.

Määritä jokainen binääribitti vuorotellen
Koska taulukon elementit ovat alueella int, voit laskea, onko vastauksen jokainen binääribitti vuorotellen 0 vai 1.

Tarkastellaan erityisesti vastauksen i:ttä binaarilukua (i on numeroitu 0:sta alkaen), joka voi olla 0 tai 1.

Vastauksen i:s numero on taulukon kaikkien elementtien i:nnen binääriluvun summan jäännös jaettuna kolmella.

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret = 0;
        for(int i=0; i<32; i++){
            int sum = 0;
            for(int num : nums){
                sum += ((num >> i) & 1);
            }
            ret += ((sum%3) << i);
        }
        return ret;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

pow(x, n)

Nopea teho + rekursio
Nopean tehon algoritmin ydin on hajota ja hallitse -algoritmi.
Alkaen x:stä, neliöi edellisen tuloksen joka kerta suoraan. Laske 5 kertaa saadaksesi x64 teho.

class Solution {
public:
    double quickMul(double x, long long N){
        if(N == 0){
            return 1.0;
        }
        double y = quickMul(x, N/2);
        return N%2 == 0 ? y * y : y * y * x;
    }
    double myPow(double x, int n) {
        long long N = n;
        return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N); 
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

nolla faktoriaalin jälkeen

Kun on annettu kokonaisluku n, palauttaa tuloksen lopussa olevien nollien lukumäärä.

Häntänollien lukumäärä n:ssä on löytää kertoimien lukumäärä 10, ja 10=2x5, joten se muunnetaan alkutekijöiden lukumäärän 2 ja alkutekijöiden lukumäärän 5 pienemmäksi arvoksi n:ssä!.

Koska alkutekijöiden 5 lukumäärä ei ole suurempi kuin alkutekijöiden 2 lukumäärä, huomioidaan vain alkutekijöiden 5 lukumäärä.

Alkutekijöiden 5 määrä n:ssä on yhtä suuri kuin kunkin luvun alkutekijöiden 5 summa.

class Solution {
public:
    int trailingZeroes(int n) {
        int res = 0;
        for(int i=5; i<=n; i += 5){
            for(int j=i; j%5 == 0; j/=5){
                res++;
            }
        }
        return res;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

pyöreä linkitetty luettelo

nopeusosoitin

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(head == nullptr || head->next == nullptr){
            return false;
        }
        ListNode* slow = head->next;
        ListNode* fast = head->next->next;
        while(fast != nullptr){
            if(slow == fast){
                return true;
            }
            if(fast->next == nullptr){
                return false;
            }
            slow = slow->next;
            fast = fast->next->next;
        }
        return false;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

Yhdistä kaksi järjestettyä linkitettyä luetteloa

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        if(list1 == nullptr){
            return list2;
        }
        if(list2 == nullptr){
            return list1;
        }
        ListNode* newHead;
        if(list1->val <= list2->val){
            newHead = list1;
            list1 = list1->next;
        }else{
            newHead = list2;
            list2 = list2->next;
        }
        ListNode* p = newHead;
        while(list1 && list2){
            if(list1->val <= list2->val){
                p->next = list1;
                p = p->next;
                list1 = list1->next;
            }else{
                p->next = list2;
                p = p->next;
                list2 = list2->next;
            }
        }

        while(list1){
            p->next = list1;
            p = p->next;
            list1 = list1->next;
        }
        while(list2){
            p->next = list2;
            p = p->next;
            list2 = list2->next;
        }
        return newHead;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

Symmetrinen binääripuu

Lisää kuvan kuvaus tähän
Puu on symmetrinen, jos sen vasen ja oikea alipuu ovat toistensa peilikuvia.

  • Niiden kahdella juurisolmulla on sama arvo
  • Jokaisen puun oikea alipuu on peilikuva toisen puun vasemmasta alipuusta

Binääripuun tason keskiarvo

leveys ensimmäinen läpikulku
Haku alkaa juurisolmusta, kulkee jokaisen kierroksen kaikkien saman kerroksen solmujen läpi, laskee kerroksen solmujen lukumäärän ja kerroksen solmujen lukumäärän summan ja laskee sitten kerroksen keskiarvon.

  • Aluksi juurisolmu asetetaan jonoon.
  • Jokaisen läpikulkukierroksen aikana kaikki jonon solmut otetaan pois, lasketaan näiden solmujen lukumäärä ja summa, minkä jälkeen lasketaan keskiarvo ja sitten kaikki solmun tyhjät lapsisolmut lisätään jonoon.
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        vector<double> average;
        queue<TreeNode *> que;
        que.push(root);
        while(!que.empty()){
            double sum = 0;
            int size = que.size();
            for(int i=0; i<size; i++){
                TreeNode* node = que.front();
                que.pop();
                sum += node->val;
                TreeNode* left = node->left;
                TreeNode* right = node->right;
                if(left){
                    que.push(left);
                }
                if(right){
                    que.push(right);
                }
            }
            average.push_back(sum / size);
        }
        return average;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

Binaaripuutason järjestyksen läpikulku

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        queue<TreeNode* > que;
        if(!root){
            return res;
        }
        que.push(root);
        while(!que.empty()){
            vector<int> temp;
            int size = que.size();
            for(int i=0; i<size; i++){
                TreeNode* node = que.front();
                que.pop();
                temp.push_back(node->val);
                TreeNode* left = node->left;
                TreeNode* right = node->right;
                if(left){
                    que.push(left);
                }
                if(right){
                    que.push(right);
                }
            }
            res.push_back(temp);
        }
        return res;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

Poista kaksoiskappaleet järjestetystä taulukosta

Järjestetyn taulukon numerot, poista toistuvat elementit paikoista, jotta elementit, jotka esiintyvät useammin kuin kahdesti, näkyvät vain kahdesti, ja palauta taulukon uusi pituus poistamisen jälkeen.

Syöttötaulukkoa on muokattava paikan päällä ja käytettävä O(1) lisätilaa.

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int left = 0;
        int right = 0;
        int n = nums.size();
        int count = 0;
        int sum = 0;
        while (right < n) {
            if (nums[left] == nums[right]) {
                count++;
                right++;
            } else {
                if (count > 1) {
                    nums[++left] = nums[left];
                    sum += 2;
                } else {
                    sum += 1;
                }
                nums[++left] = nums[right++];
                count = 1;
            }
        }
        if (count > 1) {
            nums[++left] = nums[left];
            sum += 2;
        } else {
            sum += 1;
        }
        return sum;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

Kierrä taulukkoa

Kun on annettu kokonaislukutaulukon numerot, käännä taulukon k-kohdassa olevia elementtejä oikealle.

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int n = nums.size();
        k = k % n;
        reverse(nums.begin(), nums.end());
        reverse(nums.begin(), nums.begin()+k);
        reverse(nums.begin()+k, nums.end());
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Paras aika ostaa ja myydä osakkeita

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int result = 0;
        int price = prices[0];
        for(int i=1; i<prices.size(); i++){
            if(prices[i] > price){
                result = max(result, prices[i] - price);
            }else{
                price = prices[i];
            }
        }
        return result;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Paras aika ostaa osakkeita 2

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        vector<vector<int>> dp(n,vector<int>(2)); //dp[i][0]第i天没有股票
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for(int i=1; i<n; i++){
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]);
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]);
        }
        return dp[n-1][0];
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

hyppypeli

Kun otetaan huomioon ei-negatiivinen kokonaislukutaulukko, joka sijaitsee alun perin taulukon ensimmäisessä indeksissä, jokainen taulukon elementti edustaa maksimipituutta, joka voidaan hypätä.
Selvitä, voiko se hypätä viimeiseen indeksiin.

ahne
Jos taulukon missä tahansa paikassa y on paikka x, joka voidaan saavuttaa itsestään, ja x + num[x] ≥ y, niin y voidaan myös saavuttaa.

Jokaisen saavutettavan sijainnin x kohdalla se tekee peräkkäisistä paikoista x+1, x+2, ..., x+nums[x] saavutettavissa.

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int n = nums.size();
        int rightmost = 0;
        for(int i=0; i<n; i++){
            if(i <= rightmost){
                rightmost = max(rightmost, i+nums[i]);
                if(rightmost >= n-1){
                    return true;
                }
            }
        }
        return false;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Siksak-muunnos

Kun merkkijono s on annettu, järjestä se z-muotoon ylhäältä alas ja vasemmalta oikealle annetun rivimäärän numRows mukaan.

Lisää kuvan kuvaus tähän
Simuloi käyttämällä 2D-matriiseja
Olkoon n merkkijonon s pituus, r = numRows Jos r=1 (vain yksi rivi) tai r &gt;= n (vain yksi sarake), vastaus on sama kuin s ja se voidaan palauttaa suoraan.

Muissa tapauksissa harkitse kaksiulotteisen matriisin luomista, sitten merkkijonon s täyttämistä matriisiin siksak-kuviolla ja lopuksi matriisin ei-tyhjien merkkien skannaamista rivi riviltä vastauksen muodostamiseksi.

Kysymyksen tarkoituksen mukaan, kun täytämme merkkejä matriisiin, täytämme r merkkiä alaspäin, sitten r-2 merkkiä ylöspäin oikealle ja lopuksi palaamme ensimmäiselle riville, joten Z-muotoinen muunnosjakso t = r + r - 2 = 2r - 2. Jokainen sykli vie matriisissa 1+r-2 = r-1 saraketta.

On n/t jaksoa kertaa sarakkeiden lukumäärä, mikä on yhtä suuri kuin matriisin sarakkeiden lukumäärä.

Luo matriisi, jossa on r riviä ja c saraketta, iteroi sitten merkkijonojen läpi ja täytä ne siksak-kuviolla.

class Solution {
public:
    string convert(string s, int numRows) {
        int n = s.length(), r = numRows;
        if(r == 1 || r >= n){
            return s;
        }

        //变换周期
        int t = 2*r - 2;
        int c = (n + t -1) / t * (r - 1);
        //创建二维字符串
        vector<string> mat(r, string(c, 0));
        for(int i = 0, x = 0, y =0; i<n; i++){
            mat[x][y] = s[i];
            if(i % t < r - 1){
                ++x; //向下移动
            }else{
                --x;
                ++y; //向右上移动
            }
        }

        string ans;
        for(auto &row : mat){
            for(char ch : row){
                if(ch){
                    ans += ch;
                }
            }
        }
        return ans;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

Käänteiset sanat merkkijonossa

class Solution {
public:
    vector<string> splitString(string s){
        istringstream iss(s);
        vector<string> res;
        string word;
        while(iss >> word){
            res.push_back(word);
        }
        return res;
    }
    string reverseWords(string s) {
        vector<string> words = splitString(s);
        string res;
        for(int i=words.size()-1; i>=0; i--){
            res += words[i] + " ";
        }
        res.pop_back();
        return res;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21