根據中序和先序重建二叉樹+二叉樹的鏡像+二叉樹的深度+判斷後序序列+判斷子樹

題目描述
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。

思路:遞歸。首先先序的第一個元素一定是根節點,然後在中序中以根節點爲分界,左邊的爲左子樹的所有節點,右邊的爲右子樹的所有節點,相應地也將先序劃分爲左右子樹,這樣就分別得到了左右子樹的先序和中序,遞歸地繼續調用該函數即可

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if(pre.size()==0||vin.size()==0) return NULL;

        TreeNode* root=new TreeNode(pre[0]);//先序的第一個節點爲根節點
        int rootIndex=0;
        for(int i=0;i<vin.size();i++){
            if (vin[i]==pre[0])
                rootIndex=i;//找到根節點在中序中的位置
        }
        vector<int> temppre1;
        vector<int> tempvin1;
        for(int i=0;i<rootIndex;i++){
            tempvin1.push_back(vin[i]);
            temppre1.push_back(pre[i+1]);//得到左子樹的先序和中序
        }
        vector<int> temppre2;
        vector<int> tempvin2;
        for(int i=rootIndex+1;i<vin.size();i++){
            tempvin2.push_back(vin[i]);
            temppre2.push_back(pre[i]);//得到右子樹的先序和中序
        }
        root->left=reConstructBinaryTree(temppre1,tempvin1);//左子樹遞歸,結果爲根節點的左節點
        root->right=reConstructBinaryTree(temppre2,tempvin2);  //右子樹遞歸,結果爲根節點的右節點 
        return root;
    }   
};

題目描述
操作給定的二叉樹,將其變換爲源二叉樹的鏡像。
輸入描述:
二叉樹的鏡像定義:源二叉樹
8
/ \
6 10
/ \ / \
5 7 9 11
鏡像二叉樹
8
/ \
10 6
/ \ / \
11 9 7 5

class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        if(pRoot==NULL||(pRoot->left==NULL&&pRoot->right==NULL)) return;
        TreeNode* left=pRoot->left;
        TreeNode* right=pRoot->right;
        pRoot->left=right;
        pRoot->right=left;//交換左右子樹
        Mirror(pRoot->left);//遞歸左子樹
        Mirror(pRoot->right); //遞歸右子樹   
    }
};

題目描述
輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度爲樹的深度。

class Solution {
public:
    int TreeDepth(TreeNode* pRoot)
    {
        if (pRoot==NULL) return 0;
        if(pRoot->left==NULL&&pRoot->right==NULL) return 1;
        int l=0;
        int r=0;
        if (pRoot->left!=NULL){
            l=TreeDepth(pRoot->left);//左子樹的深度
        }
        if(pRoot->right!=NULL){
            r=TreeDepth(pRoot->right);//右子樹的深度
        }
        return max(l,r)+1; //樹的深度爲左右子樹的最大值+1
    }
};

題目描述
輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。
思路:分別求出左右子樹的深度,判斷深度之差絕對值小於2,且左右子樹爲平衡二叉樹

class Solution {
public:
    int TreeDepth(TreeNode*pRoot){
        if (pRoot==NULL) return 0;
        if(pRoot->left==NULL&&pRoot->right==NULL) return 1;
        int l=0;
        int r=0;
        if (pRoot->left!=NULL){
            l=TreeDepth(pRoot->left);//左子樹的深度
        }
        if(pRoot->right!=NULL){
            r=TreeDepth(pRoot->right);//右子樹的深度
        }
        return max(l,r)+1; //樹的深度爲左右子樹的最大值+1
    }

    bool IsBalanced_Solution(TreeNode* pRoot) {
        if(pRoot==NULL||(pRoot->left==NULL&&pRoot->right==NULL)) return true;
        int l=0;
        int r=0;
        if(pRoot->left!=NULL) l=TreeDepth(pRoot->left);
        if(pRoot->right!=NULL) r=TreeDepth(pRoot->right);
        if(IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right)&&abs(l-r)<2) return true;        return false;


    }
};

題目描述
輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        int l=sequence.size();
        if(l==0) return false;
        if(l<=2) return true;
        int num=sequence[l-1]; //最後一個元素num作爲分界線
        int i=0;
        int j=l-2; //要先將最後一個元素排除
        while(i<l&&sequence[i]<num) i++; //找到比num小的連續序列
        while(j>=0&&sequence[j]>num) j--;//找到比num大的連續序列
        vector<int> left;
        vector<int> right;
        for(int k=0;k<i;k++) left.push_back(sequence[k]);
        for(int k=j+1;k<l-1;k++) right.push_back(sequence[k]); //注意此處爲k<l-1        
        return ((left.empty()&&VerifySquenceOfBST(right)&&i==j+1)||(right.empty()&&VerifySquenceOfBST(left)&&i==j+1)||(i==j+1&&VerifySquenceOfBST(left)&&VerifySquenceOfBST(right))); //首先根據最後一個元素可以將vector完全分爲兩部分(即i=j+1),之後有三種情況:(1)左邊爲空,右邊爲後序序列;(2)右邊爲空,左邊爲後序序列;(3)左右均爲後序序列
    }
};

題目描述
輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)
思路:使用遞歸算法,首先在1樹中找與2樹的根節點值相同的節點,然後判斷以該節點爲根的子樹是否與2樹相同。

class Solution {
public:
    bool IsSubTree(TreeNode* pRoot1, TreeNode* pRoot2){
        if(pRoot2==NULL) return true;
        if(pRoot1==NULL) return false;
        if(pRoot1->val!=pRoot2->val) return false;
        return (pRoot1->val==pRoot2->val&&IsSubTree(pRoot1->left,pRoot2->left)&&IsSubTree(pRoot1->right,pRoot2->right));//節點值相等且左右子樹都相同
    }
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        bool result=false;
        if(pRoot2==NULL||pRoot1==NULL) return false;
        if(pRoot1->val==pRoot2->val){
            result=IsSubTree(pRoot1,pRoot2);//如果節點的值相等,就判斷是否是相同樹
        }
        if(!result&&pRoot1->left!=NULL){
            return HasSubtree(pRoot1->left,pRoot2);//如果節點值不相等,就判斷左子樹中有沒有pRoot2的子結構
        }
        if(!result&&pRoot1->right!=NULL){
            return HasSubtree(pRoot1->right,pRoot2);
        }
        return result;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章