題目描述
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{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;
}
};