本文最后更新于:2022年4月9日 中午
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
| 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3]
|
返回如下的二叉树:
Solution
其他类似题型 [105 从前序与中序遍历序列构造二叉树] 、[654 最大二叉树]
参考 代码随想录
第一步:如果数组大小为零的话,说明是空节点了。
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
第五步:切割后序数组,切成后序左数组和后序右数组。(后序数组就可以按照左中序数组的大小来切割,切成左后序数组和右后序数组。)
第六步:递归处理左区间和右区间

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
class Solution { private: TreeNode* traversal (vector<int>& inorder, vector<int>& postorder) { if (postorder.size() == 0) return NULL;
int rootValue = postorder[postorder.size() - 1]; TreeNode* root = new TreeNode(rootValue);
if (postorder.size() == 1) return root;
int delimiterIndex; for (delimiterIndex = 0; delimiterIndex < inorder.size(); delimiterIndex++) { if (inorder[delimiterIndex] == rootValue) break; }
vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterIndex); vector<int> rightInorder(inorder.begin() + delimiterIndex + 1, inorder.end() );
postorder.pop_back();
vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size()); vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());
root->left = traversal(leftInorder, leftPostorder); root->right = traversal(rightInorder, rightPostorder);
return root; } public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { if (inorder.size() == 0 || postorder.size() == 0) return NULL; return traversal(inorder, postorder); } };
|
- 优化,用下标索引来分割,避免构造 vector 容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| class Solution { public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { if (inorder.size() == 0 || postorder.size() == 0) return nullptr; return traversal(inorder, 0, inorder.size(), postorder, 0, postorder.size()); } private: TreeNode* traversal(vector<int>& inorder, int inorderBegin, int inorderEnd, vector<int>& postorder, int postorderBegin, int postorderEnd) { if (postorderBegin == postorderEnd) return nullptr;
int rootVal = postorder[postorderEnd - 1]; TreeNode* root = new TreeNode(rootVal); if (postorderEnd - postorderBegin == 1) return root;
int delimiterIndex; for (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) { if (inorder[delimiterIndex] == rootVal) break; } int leftInorderBegin = inorderBegin; int leftInorderEnd = delimiterIndex; int rightInorderBegin = delimiterIndex + 1; int rightInorderEnd = inorderEnd;
int leftPostorderBegin = postorderBegin; int leftPostorderEnd = postorderBegin + delimiterIndex - inorderBegin; int rightPostorderBegin = postorderBegin + (delimiterIndex - inorderBegin); int rightPostorderEnd = postorderEnd - 1;
root->left = traversal(inorder, leftInorderBegin, leftInorderEnd, postorder, leftPostorderBegin, leftPostorderEnd); root->right = traversal(inorder, rightInorderBegin, rightInorderEnd, postorder, rightPostorderBegin, rightPostorderEnd);
return root; } };
|