本章leetcode题解
654.最大二叉树(难度 Medium)
105.从前序与中序遍历序列构造二叉树(难度 Medium)
106.从中序与后序遍历序列构造二叉树(难度 Medium)
上一篇讲到刷二叉树时需要注意顺序+当前节点操作。今天涉及的三道题实际上还是这么大回事,只不过递归的时候同时引入了分治,因此需要考虑一些边界。
654 最大二叉树
题目种给出的定义其实挺清楚了。对于一个最大二叉树的建造实际上就是。
根为树中的最大元素,并且左右子树也是最大二叉树。
OK!那么对于我们就是要找准左右部分,然后交给递给继续去构建最大二叉树就完事了。
其实还是前序遍历(对应范围)+当前操作(取此时数组的最大值)。
不过要注意边界范围,容易犯错。
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
int size = nums.size();
if(size == 0) return NULL;
return constructMax(nums,0,nums.size()-1);
}
TreeNode* constructMax(vector<int>& nums,int left,int right){
if(left>right) return NULL;
int max=INT_MIN;
int maxIndex;
//找到最大数和最大小标
for(int i = left;i<=right;i++){
if(nums[i]>max){
max = nums[i];
maxIndex =i;
}
}
//节点处理
TreeNode* root = new TreeNode;
root->val = nums[maxIndex];
root->left = constructMax(nums,left,maxIndex-1);
root->right =constructMax(nums,maxIndex+1,right);
return root;
}
};
105.从前序与中序遍历序列构造二叉树(难度 Medium)
OK,给出两个序列叫你构建二叉树。那自然我们要分析下这两个序列能给我们提供一些什么信息。前序遍历意味着我们能够轻松的知道对应的根节点,有了根节点就相当于找到了主心骨。这之后就是要问问左右子树怎么来。
既然我们已经知道根节点元素,即对应前序数组的第一个元素。那么我们在中序遍历中找到这个元素是不是就自然的把元素分成左右两个部分了呢?
因此,思路已经梳理出来。前序遍历提供根节点,中序遍历根据根节点能够分出左右子树的长度。剩下的当然就交给递归序列接着去做了。
还是要注意范围,不熟悉的可以画个图,或者带个值想想。
(图源:labuladong)
代码如下:
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return build(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);
}
TreeNode* build(vector<int>& preorder,vector<int>& inorder,int preL,int preR,int inL,int inR){
if(preL>preR) return NULL;
int k; //定位根
for(int i = inL;i<=inR;i++){
if(preorder[preL]==inorder[i]){
k = i;
break;
}
}
TreeNode* root = new TreeNode(preorder[preL]);
root->left = build(preorder,inorder,preL+1,preL+k-inL,inL,k-1);
root->right = build(preorder,inorder,preL+k-inL+1,preR,k+1,inR);
return root;
}
};
106.从中序与后序遍历序列构造二叉树(难度 Medium)
和上一题一样的思路,只需要思考好范围就能写出。
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return build(inorder,postorder,0,inorder.size()-1,0,postorder.size()-1);
}
TreeNode* build(vector<int>&inorder,vector<int>&postorder,int inL,int inR,int postL,int postR){
if(postL>postR) return NULL;
int k; //找到位置
for(int i = inL;i<=inR;i++){
if(postorder[postR]==inorder[i]){
k = i;
break;
}
}
TreeNode* root = new TreeNode(postorder[postR]);
root->left = build(inorder,postorder,inL,k-1,postL,postL+k-inL-1);
root->right = build(inorder,postorder,k+1,inR,postL+k-inL,postR-1);
return root;
}
};
推荐文章
https://mp.weixin.qq.com/s/OlpaDhPDTJlQ5MJ8tsARlA