根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3 / 9 20 / 15 7
一开始我没有理解构造一棵树的意思,之前这一类的题,我接触到的都是返回某一种遍历顺序的数组,后来参考他人的解答,
才知道构建一棵树,其实就是通过链表形式构建一棵树,返回根结点
解决树的问题,基本思维是用递归的方法
中序遍历:
- 访问根结点
- 根节点的左结点进行中序遍历
- 根结点的右结点进行中序遍历
后序遍历:
- 后序遍历根结点左子树
- 后序遍历根节点右子树
- 访问根结点
树的遍历都是用递归的思维来实现的
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
3
/ 9 20 / 15 7
通过观察遍历的结果可以发现,后序遍历最后遍历的是根结点,中序遍历中,根结点左边的
是树的左子树,根节点右边的是树的右子树
在这个例子中后序遍历的最后一个是3,那么在中序遍历中9是树的左子树,15,20,7是树的右子树
根据上一步求到的左子树,和右子树的长度,再把后序遍历根据长度分为左子树,右子树。
在进行和上面一样的遍历
下面展示一下递归的实现过程
递归的最开始是从inorder,postorder整个数组开始的
dfs(inorder, postorder, 0, 4, 0, 4)
root->val = postorder[4] = 9 #这个即为根节点的值,实现过程可以参考下面的程序
i = 1; #找到9在inorder中的位置
root->left = dfs(inorder, postorder, 0, 0, 0, 0) #通过递归找到根结点的左结点
root->val = postorder[0] = 9;
i = 0;
root->left = dfs(inorder, postorder, 0, -1, 0, -1)
return null;
root->right = dfs(inorder, postorder,1, 0, 1, 0)
return null;
root->right = dfs(inorder, postorder, 2, 4, 1, 3) #通过递归找到根结点的右结点
root->val = postorder[3] = 20
i = 3
root->left = dfs(inorder, postorder, 2, 2, 1, 1)
root->val = postorder[1] = 15
i = 2;
root->left = dfs(inorder, postorder, 2, 1, 1, 0)
return null;
root->right = dfs(inorder, postorder, 3, 2, 2, 1)
return null;
root->right = dfs(inorder, postorder, 4, 4, 2, 2)
root->val = postorder[2] = 7
i = 4;
root->left = dfs(inorder, postorder, 4, 3, 2, 1)
return null
root->right = dfs(inorder, postorder, 5, 4, 2, 1)
return null;
return root;
递归终止于左边序列大于右边序列
大家按照上面的过程推导一次,就能大概的理解到由中序,遍历前序的方法了
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 TreeNode* dfs(vector<int>& inorder, vector<int>& postorder, int inl, int inr, int postl, int postr){ 13 if(inl > inr) return NULL; 14 TreeNode* root = new TreeNode(postorder[postr]); 15 int i = inl; 16 while(inorder[i] != postorder[postr] && i < inr) i++; 17 root->left = dfs(inorder, postorder, inl, i-1, postl, postl+i-inl-1); 18 root->right = dfs(inorder, postorder, i+1, inr, postl+i-inl, postr-1); 19 return root; 20 } 21 TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { 22 int l = inorder.size()-1; 23 return dfs(inorder, postorder, 0, l, 0, l); 24 } 25 };