889. 根据前序和后序遍历构造二叉树
【题目描述】给定两个整数数组,preorder 和 postorder ,其中 preorder 是一个具有 无重复 值的二叉树的前序遍历,postorder 是同一棵树的后序遍历,重构并返回二叉树。
如果存在多个答案,您可以返回其中 任何 一个。
【示例 1】
输入:preorder = [1,2,4,5,3,6,7], postorder = [4,5,2,6,7,3,1]
输出:[1,2,3,4,5,6,7]
【示例 2】
输入: preorder = [1], postorder = [1]
输出: [1]
【提示】
1 <= preorder.length <= 30
1 <= preorder[i] <= preorder.length
preorder 中所有值都 不同
postorder.length == preorder.length
1 <= postorder[i] <= postorder.length
postorder 中所有值都 不同保证 preorder 和 postorder 是同一棵二叉树的前序遍历和后序遍历
来源:力扣(LeetCode)
链接:889. 根据前序和后序遍历构造二叉树
【求解思路】
前序遍历序列中根节点始终在首位,后序遍历序列中的根节点在末尾,一般的求解方法如下:
1.找到二叉树的根节点,根据前序序列确定后序序列中左右子树
2.先构建左子树,方法同1
3.构建右子树,方法同1
具体的算法:
1.确定左边界,右边界;左边界中包含的所有左子树中的元素,右边界中包含的是所有右子树的元素。如果当前元素的下一个在当前元素的范围内,则可以将当前的范围划分为左右,如果不在,则回溯;
2.对于最后一个元素不存在下一位,则直接回溯即可
3.需要回溯的情况:左边界大于右边界、当前元素不在范围内
/**
* 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:
int cur_pos;
vector<int> pre;
vector<int> post;
int findNode(int n,int start,int end){
for(int i = start;i<=end;i++){
if(post[i] == n)return i;
}
return -1;
}
TreeNode* createTree(int left_pos,int right_pos){
if(left_pos>right_pos || cur_pos>pre.size()-1){
if(left_pos>right_pos)cur_pos--;
return nullptr;
}
int post_pos = findNode(pre[cur_pos],left_pos,right_pos);
if(post_pos == -1){
cur_pos --;
return nullptr;
}
TreeNode *root = new TreeNode;
root->val = pre[cur_pos];
int left_tree = -2;
if(cur_pos != pre.size()-1)left_tree = findNode(pre[cur_pos+1],left_pos,right_pos);
cur_pos++;
root->left = createTree(left_pos,left_tree);
cur_pos++;
root->right = createTree(left_tree+1,right_pos);
return root;
}
TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {
pre = preorder;
post = postorder;
cur_pos = 0;
return createTree(0,preorder.size()-1);
}
};