递归法解决二叉树系列问题
构造二叉树问题
- 构造出根结点。
- 递归构造出左子树、右子树。
- 返回根结点。
最大二叉树
1.找出当前序列中的最大值,构造出根结点。
2.然后根据最大值的位置左右划分出两个子序列,递归构造出左右子树。
3.返回根结点。
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return bulid(nums,0,nums.size()-1);
}
TreeNode* bulid(vector<int>& nums,int l,int r){
if(l > r)
return NULL;
int index = -1;
int maxVal = INT_MIN;
for(int i = l;i <= r;i++){
if(nums[i]> maxVal){
index = i;
maxVal = nums[i];
}
}
TreeNode *root = new TreeNode(maxVal);
root->left = bulid(nums,l,index-1);
root->right = bulid(nums,index + 1,r);
return root;
}
};
由前序序列中序序列构造二叉树
前序序列=根+左子树前序序列+右子树前序序列
中序序列=左子树中序序列+根+右子树中序序列
1.由前序序列的第一个元素值构造出根结点。
2.在中序序列中找到根结点值的位置,由此位置划分出左右两个子序列,这两个子序列分别为左子树和右子树的中序序列。
由左子树的中序序列长度可以得到左子树和右子树的的前序序列长度。根据此长度在前序序列中划分出左右子树的前序序列。由左前序和左中序构造出左子树,由右前序和右中序构造出左子树。
3.最后返回根结点。
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return build(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
}
TreeNode* build(vector<int>& preorder,int preStart,int preEnd,vector<int>& inorder,int inStart,int inEnd){
if(preStart>preEnd || inStart>inEnd)
return nullptr;
int rootVal = preorder[preStart];
int index = 0;
for(int i = inStart;i <= inEnd;i++){
if(inorder[i] == rootVal)
index = i;
}
int leftSize = index - inStart;
TreeNode *root = new TreeNode(rootVal);
root->left = build(preorder, preStart + 1,preStart + leftSize ,inorder, inStart,index - 1);
root->right = build(preorder, preStart + leftSize + 1, preEnd,inorder, index + 1,inEnd);
return root;
}
};
由后序序列和中序序列构造二叉树
后序序列=左子树后序序列+右子树后序序列+根
中序序列=左子树中序序列+根+右子树中序序列
1.由后序序列的最后一个元素值构造出根结点。
2.在中序序列中找到根结点值的位置,由此位置划分出左右两个子序列,这两个子序列分别为左子树和右子树的中序序列。
由左子树的中序序列长度可以得到左子树和右子树的的后序序列长度。根据此长度在后序序列中划分出左右子树的后序序列。由左后序和左中序构造出左子树,由右后序和右中序构造出左子树。
3.最后返回根结点。
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return build(inorder,0,inorder.size()-1,postorder,0,postorder.size()-1);
}
TreeNode *build(vector<int>& inorder,int inStart,int inEnd, vector<int>& postorder,int postStart,int postEnd){
if(inStart>inEnd || postStart>postEnd)
return nullptr;
int rootVal = postorder[postEnd];
int index = 0;
for(int i = inStart;i <= inEnd;i++){
if(inorder[i] == rootVal)
index = i;
}
int leftSize = index - inStart;
TreeNode *root = new TreeNode(rootVal);
root->left = build(inorder,inStart,index - 1,postorder,postStart,postStart + leftSize -1);
root->right = build(inorder,index + 1,inEnd,postorder,postStart + leftSize,postEnd - 1);
return root;
}
};