题目链接:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
首先要知道一个结论,前序/后序+中序序列可以唯一确定一棵二叉树,所以自然而然可以用来建树。
看一下后序和中序有什么特点,后序[9,15,7,20,3]
,中序[9,3,15,20,7]
;
有如下特征:
inRoot
;intleftLen = inRoot - inLeft
;;root->left = buildTreeCore(后序左子树范围,中序左子树范围,后序序列,中序序列);
;root->right = buildTreeCore(后序右子树范围,中序右子树范围,后序序列,中序序列);
。root
;时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.empty()||postorder.empty()||inorder.size() != postorder.size()) return nullptr;
return buildTreeCore(0, inorder.size()-1, 0, inorder.size()-1, postorder, inorder);
}
TreeNode* buildTreeCore(int posLeft, int posRight, int inLeft, int inRight, vector<int>& posorder, vector<int>& inorder){
if(posLeft>posRight || inLeft>inRight) return nullptr;
TreeNode* root = new TreeNode(posorder[posRight]); // 后序遍历最后节点为根节点
int inRoot = inLeft; // 中序遍历中根节点的位置
while (inRoot <= inRight && inorder[inRoot] != posorder[posRight]) ++ inRoot;
int leftLen = inRoot - inLeft; // 左子树的长度,也是根节点在中序中的位置
root->left = buildTreeCore(posLeft, posLeft + leftLen-1, inLeft, inRoot-1, posorder,inorder);
root->right = buildTreeCore(posLeft+leftLen, posRight-1, inRoot+1, inRight, posorder,inorder);
return root;
}
};