题目:前序+中序 or 中序+后序 -> 构建二叉树
前提:
1.前序:root->left->right
2.中序:left->root->right
3.后序:left->right->root
e.g. 有以下的二叉树:
前序(preorder): [1, 2, 4, 8, 5, 9, 10, 3, 6, 11, 7, 12]
中序(inorder): [8, 4, 2, 9, 5, 10, 1, 6, 11, 3, 12, 7]
后序(postorder):[8, 4, 9, 10, 5, 2, 11, 6, 12, 7, 3, 1]
解题方针:
1,顺序遍历【前序】or【后序】,确定每一层的 root
2,遍历【中序】,找到 root 的位置,root 以左:left,root 以右:right
3,递归分别再把 left 和 right 的数列看作一棵树,重复1,2
注意点:
1,确定每次递归数列在【中序】的 开始 和 结束 位置。
例如:上述例子在【前序】(正序遍历)的第一个 root 为 1,【后序】(倒序遍历)的第一个root 为 1
则【中序】中找到的 1,的 index 为 6(MidIndex)
即 left 的 index 范围为【0(inStart)~5 (MidIndex-1)】,right 的 index 范围为【7(MidIndex+1)~11(inEnd)】
left 的长度为:【6(MidIndex-inStart)】,right 的长度为:【5(inEnd-MidIndex)】
*2,确定每次递归传入的【前序】or【后序】的 root 位置
例如:上述例子中,
对于【前序】:left 树的root位置为:上次root的位置+1【即(preStart+1)】
对于【前序】:right 树的root位置为:上次root的位置+left树的长度+1【即(preStart+(MidIndex-inStart)+1)】
对于【后序】:left 树的root位置为:上次root的位置-right树的长度-1【即(preStart-(inEnd-MidIndex)-1)】
对于【后序】:right 树的root位置为:上次root的位置-1【即(preStart-1)】
参考代码:
【前序】+【中序】
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* helper(vector<int>& preorder, vector<int>& inorder, int preStart, int inStart, int inEnd){ 13 int inMidi = 0; 14 if(preStart > preorder.size()-1 || inStart > inEnd) return NULL; 15 TreeNode* root = new TreeNode(preorder[preStart]); 16 for(int i=inStart; i<=inEnd; i++){ 17 if(inorder[i] == root->val){ 18 inMidi = i; 19 break; 20 } 21 } 22 root->left = helper(preorder, inorder, preStart+1, inStart, inMidi-1); 23 root->right = helper(preorder, inorder, preStart+inMidi-inStart+1, inMidi+1, inEnd); 24 return root; 25 } 26 TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { 27 TreeNode* res=NULL; 28 res = helper(preorder, inorder, 0, 0, inorder.size()-1); 29 return res; 30 } 31 };
【后序】+【中序】
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* helper(vector<int>& inorder, vector<int>& postorder, int inStart, int inEnd, int postEnd){ 13 if(inStart > inEnd) return NULL; 14 if(postEnd < 0) return NULL; 15 TreeNode* root = new TreeNode(postorder[postEnd]); 16 int midIndex=0; 17 for(int i=inStart; i<=inEnd; i++){ 18 if(inorder[i]==root->val){ 19 midIndex = i; 20 break; 21 } 22 } 23 root->left=helper(inorder, postorder, inStart, midIndex-1, postEnd - (inEnd-midIndex) -1); 24 root->right=helper(inorder, postorder, midIndex+1, inEnd, postEnd-1); 25 return root; 26 } 27 TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { 28 TreeNode* res; 29 res = helper(inorder, postorder, 0, inorder.size()-1, postorder.size()-1); 30 return res; 31 } 32 };