Teknologian jakaminen

Algoritmi pyrkii vähentämään neljäkymmentäkaksi kysymystietuetta [101. Symmetrinen binääripuu, 100. Identtinen puu, 572. Toisen puun alipuu].

2024-07-12

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

Esipuhe

Aloita binääripuiden toiminnan harjoittelu luvussa Binaaripuu.
Tietue 42 [101.
jatkaa.


1. Aiheen lukeminen

Anna sinulle binääripuun juurisolmun juuri, Tarkista, onko se aksiaalisesti symmetrinen

Esimerkki 1:
Lisää kuvan kuvaus tähän

输入:root = [1,2,2,3,4,4,3]
输出:true
  • 1
  • 2

Esimerkki 2:
Lisää kuvan kuvaus tähän

输入:root = [1,2,2,null,3,null,3]
输出:false
  • 1
  • 2

vihje:

树中节点数目在范围 [1, 1000] 内
-100 <= Node.val <= 100
  • 1
  • 2

Edistynyt: Voit käyttääRekursio ja iteraatioKaksi tapaa ratkaista tämä ongelma?


2. Yritä ymmärtää

Idea 1

Kokeile ensin rekursiota. Ydin: Mitkä ovat kriteerit aksiaalisen symmetrian arvioinnissa?

Rekursio: Soita itsellesi.Päällekkäistä logiikkaa ei vielä löytynyt

  • Määritä vasen==oikea? Alipuun syöttäminen on väärin.
  • Vasen alipuu menee vasemmalle, keskelle ja oikea alipuu oikealle, vasemmalle, keskelle. Ovatko sekvenssit yhtäläiset? Mutta se koskee koko puuta. Myös alipuun syöttäminen on väärin.

Idea 2

Käytä iteratiivista lähestymistapaa muutokseen. Käytä tasotilauksen läpikulkua.
Kerrossekvenssituloksen saamisen jälkeen päätellään, että jokainen kerros on parillinen luku ja yhtä suuri käänteisenä. Mutta esimerkiksi kaksi, tämä ei ole totta, koska nollaosoitin on poissuljettu.
Idea ei toimi.

Yhteenveto:Vaikka tiedämme, että meidän on etsittävä symmetriaa, meillä ei ole yhtenäistä standardia symmetrian arvioimiseksi.


3. Viiteideoita

Viitelinkki

Oppimissisältö

  • Aksiaalinen symmetria: Voidaanko juurisolmun vasen ja oikea alipuu kääntää tasa-arvoisiksi? , miten vertailla?
  • Selityksestä saatuoikea idea: Tämä läpikulku vaatii juurisolmun vasemman alipuun ja juurisolmun oikean alipuun.Kuljeta samanaikaisesti . Vain kulkemalla kahta alipuuta kerralla voimme arvioida, ovatko solmut molemmilla puolilla yhtä suuret.
    • Ohita ensin vasemman alipuun vasen puoli ja oikean alipuun oikea puoli. Tällä hetkellä ulompien solmujen katsotaan olevan yhtä suuria.
    • Ohita sitten vasemman alipuun oikea puoli ja oikean alipuun vasen puoli. Tällä hetkellä sisempien solmujen katsotaan olevan yhtä suuria.
    • Molempien palautusten jälkeen ne ovat tosia samaan aikaan, mikä osoittaa symmetriaa.
  • Määritä läpikulkujärjestys: vasen, oikea, keski. Käsiteltyäsi vasemman lapsen, käsittele oikea lapsi uudelleen ja palauta tulos keskisolmuun.
  • Yritetään toteuttaaIdeoiden riittämättömyys : Käsittele vain juurisolmun vasen alipuu ja huomaa, että juurisolmun oikean alipuun järjestys on erilainen kuin vasemman alipuun. Et voi saada yhtenäistä logiikkaa kääntämällä läpikulkujärjestystä tai mitä tahansa.

Rekursiivinen toteutus

Jokainen kommentti on idea.

/**
 * 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:
    bool iscompare(TreeNode* left,TreeNode* right){ //两边同时遍历,所以两个参数。返回是否相等,用bool类型。
        //确定终止条件
        if(!left && !right) return true;    //同时为空,可以翻转
        else if(!left && right) return false; //一个空,一个不为空。肯定不等
        else if (!right && left) return false;//一个空,一个不为空。肯定不等
        else if(left->val != right->val) return false;//都不为空,但是值不等

        //都不为空,值相等。说明可以继续进行外侧比较、内侧比较,不用return。
        bool outside = iscompare(left->left,right->right);  //同时比较,解决了左右遍历顺序不一样
        bool inside = iscompare(left->right,right->left);
        return outside && inside;   //同时返回true。才能返回true
    }
    bool isSymmetric(TreeNode* root) {
        return iscompare(root->left,root->right);
    }
};
  • 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

Puun läpikulkujärjestys (vasen alipuu) on vasen-keski ja puun (oikea alipuu) läpikulkujärjestys on oikea-vasen-keski.

Iteratiivinen idea 1

  • Käsittele juurisolmun vasen alipuu ja juurisolmun oikea alipuu samanaikaisesti. Se on erilainen kuin edellinen läpikulku.
  • Käytä jonorakennetta: putKaksi vertailtavaa solmua asetetaan jonoon samanaikaisesti,UudelleenOta se pois samalla . Selvitä, voidaanko kaksi purettua solmua kääntää. Joten jos vasen ja oikea lapset ovat vapaita, ne on myös asetettava jonoon.
  • Käytä pinorakennetta: täytyy silti käsitellä kaksi solmua samanaikaisesti. Vertailevia kohteita on kaksi.Laita se sisään ja ota se ulos samanaikaisesti

Iteratiivinen toteutus [jonorakenne]

Pinorakenne on sama.

/**
 * 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:
    bool isSymmetric(TreeNode* root) {
        if(!root) return false;
        queue<TreeNode*> que;
        que.push(root->left);//放入左子树
        que.push(root->right);//放入右子树
        while(!que.empty()){
            TreeNode* left = que.front(); que.pop();//取出比较对象中的左节点
            TreeNode* right = que.front();que.pop();//取出比较对象中的右节点

            if(!left && !right){    //都是空节点
                continue;
            }else if(!left || !right || left->val != right->val){
                return false;
            }

            que.push(left->left);
            que.push(right->right);
            que.push(left->right);
            que.push(right->left);
        }
        return true;
    }
};
  • 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

Yhteenveto [Axisymmetric Binary Tree]:

  • Se on edelleen läpikulkua, ero on:Molemmat alipuut on ajettava samanaikaisesti . Ei ole oikein palata syvälle mihinkään alipuuhun.
  • Objektien vertailun ehdot tosi: molemmat ovat tyhjiä tai arvot ovat samat. Loput ovat vääriä.
  • Mitään alipuuta ei myöskään voi kulkea rekursiivisesti, koska vasemman ja oikean puolen järjestys on erilainen.
  • Se ei ole tasojärjestyksen läpikulku. Jos sinun täytyy kulkea taso peräkkäin: hanki kunkin tason tulokset, käännä ja tarkista sitten, ovatko ne yhtä suuret. Seuraavaksi (ei suositella), yllä olevat vastaukset ovat kaikki erittäin hyviä.
/**
 * 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:
    bool isSymmetric(TreeNode* root) {
        vector<vector<int>> level;
        queue<TreeNode*> que;
        if(!root) return false;
        que.push(root);
        while(!que.empty()){
            int size = que.size();
            vector<int> vec;
            while(size--){
                TreeNode* cur = que.front();que.pop();
                if(cur){ //不是空节点
                    que.push(cur->left);
                    que.push(cur->right);
                    vec.push_back(cur->val);
                }else{
                    vec.push_back(INT_MIN);//因为节点的值【-100,100】。用一个最小值代表空。
                }
            }
            level.push_back(vec);
        }
        //获得层序遍历。包含空。空的数值借助INT_MIN代替。
        for(int i = 1;i < level.size();i++){
            vector<int> temp = level[i];
            reverse(temp.begin(),temp.end());
            if(temp != level[i]){
                return false;
            }
        }
        return true;

    }
};
  • 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

Kysymyskäytäntö

【100. Sama puu】

1. Otsikko

Kun on annettu kahden binaaripuun juurisolmut p ja q, kirjoita funktio testataksesi, ovatko nämä kaksi puuta samat.

Jos kaksi puutaRakenteellisesti sama ja solmuilla on samat arvot, niitä pidetään samanlaisina.

Esimerkki 1:

输入:p = [1,2,3], q = [1,2,3]
输出:true
  • 1
  • 2

Esimerkki 2:

输入:p = [1,2], q = [1,null,2]
输出:false
  • 1
  • 2

Esimerkki 3:

输入:p = [1,2,1], q = [1,1,2]
输出:false
  • 1
  • 2

vihje:

两棵树上的节点数目都在范围 [0, 100] 内
-10^4 <= Node.val <= 10^4
  • 1
  • 2

Ideoita

Selvitä, ovatko kaksi puuta samanlaisia. Rakenne on sama ja arvot ovat samat.

  • Sitten täytyyVain kun kahta puuta käsitellään samanaikaisesti, voi olla vertailukohde. . On hyödytöntä vain kävellä syvälle / tehdä mitään puun toimintoa.
  • Erot [101. Symmetric Binary Tree] -vertailuobjekteista.tässäVertailuobjektin vasenta lasta verrataan vasempaan lapseen; . Rekursiivisen kutsun parametrit on annettu.

Koodi

/**
 * 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:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(!p && !q) return true;  //传入节点同时为空,可以对应
        else if(!p && q) return false;//一个空,另一个不是空。不可能对应。
        else if(p && !q) return false;//一个空,另一个不是空。不可能对应。
        else if(p->val != q->val) return false;//值不等,不可能对应。

        bool leftchild = isSameTree(p->left,q->left); 
        bool rightchild = isSameTree(p->right,q->right);
        return leftchild && rightchild;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

【572.Toisen puun osapuu】

aihe

Sinulle annetaan kaksi binaaripuuta juuri ja alijuuri.Tarkista sisältääkö root ja subRoot onSama rakenne ja solmuarvot alipuu. Jos läsnä, palauttaa tosi, muussa tapauksessa palauttaa epätosi.

Binääripuun alipuu sisältää puun solmun ja kaikki tämän solmun jälkeläiset solmut. puuta voidaan pitää myös alipuuna itsestään.

Esimerkki 1:

输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true
  • 1
  • 2

Esimerkki 2:

输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false
  • 1
  • 2

vihje:

root 树上的节点数量范围是 [1, 2000]
subRoot 树上的节点数量范围是 [1, 1000]
-10^4 <= root.val <= 10^4
-10^4 <= subRoot.val <= 10^4
  • 1
  • 2
  • 3
  • 4

Ideoita

(1) Alipuut arvioivat myös kaksi puuta samanarvoisiksi. Voit käyttää [100 Question Code Implementation] ratkaistaksesi tasa-arvopäätöksen.
(2) Mutta se on löydettävä juurestaSama kuin alijuuren juurisolmun arvo solmu alipuun juurisolmuna. Läpi juuren läpi tasojärjestyksen mukaan.

Koodi

/**
 * 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:
    bool isSame(TreeNode* rootnode,TreeNode* subRootnode){
        if(!rootnode && !subRootnode) return true;
        else if(!rootnode && subRootnode) return false;
        else if(rootnode && !subRootnode) return false;
        else if(rootnode->val != subRootnode->val) return false;

        bool leftchild = isSame(rootnode->left,subRootnode->left);
        bool rightchild = isSame(rootnode->right,subRootnode->right);
        return leftchild && rightchild;
    }
    bool isSubtree(TreeNode* root, TreeNode* subRoot) {
        //先找到和subRoot值相等的节点,才有可能相等。得遍历root找到和subRoot值相等的节点,可能作为子树的根节点

        //用层序遍历
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()){
            int size = que.size();
            while(size--){
                TreeNode* cur = que.front();que.pop();
                if(cur->val == subRoot->val){
                    bool subtree = isSame(cur,subRoot);
                    if(subtree) return true;
                }
                if(cur->left) que.push(cur->left);
                if(cur->right) que.push(cur->right);
            }
        }
        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
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

Koko teksti yhteenveto

Ydin: Selaa kahta puuta samanaikaisesti määrittääksesi vertailuobjektin. Suorita rekursiivinen toteutus.

Mikään syvempi puun läpikulku ei tuota vertailua kohteen molemmista puolista.

(Oikaisu on tervetullut, ilmoita lähde uusintapainoksessa)