72. Construct Binary Tree from Inorder and Postorder Traversal
Given inorder and postorder traversal of a tree, construct the binary tree.
Example
Example 1:
Input:[],[]
Output:{}
Explanation:
The binary tree is null
Example 2:
Input:[1,2,3],[1,3,2]
Output:{2,1,3}
Explanation:
The binary tree is as follows
2
/ \
1 3
Notice
You may assume that duplicates do not exist in the tree.
Input test data (one parameter per line)How to understand a testcase?
解法1:
根据postOrder的最后一个节点为根节点找到其在inOrder中的位置,然后就可以找出左子树的节点范围和右子树的节点范围进行递归。
注意:
1) 在对右子树递归时,需要减去最后一个节点即根节点。
root->right = helper(inorder, rootIndex + 1, inEnd, postorder, postEnd - rightTreeCount, postEnd - 1);
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param inorder: A list of integers that inorder traversal of a tree
* @param postorder: A list of integers that postorder traversal of a tree
* @return: Root of a tree
*/
TreeNode * buildTree(vector<int> &inorder, vector<int> &postorder) {
return helper(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1);
}
private:
TreeNode * helper(vector<int> &inorder, int inStart, int inEnd, vector<int> &postorder, int postStart, int postEnd) {
if (inStart > inEnd || inEnd < 0 || postEnd < 0) {
return NULL;
}
TreeNode * root = new TreeNode(postorder[postEnd]);
int rootIndex = 0;
for (int i = inStart; i <= inEnd; ++i) {
if (inorder[i] == postorder[postEnd]) {
rootIndex = i;
break;
}
}
int leftTreeCount = rootIndex - inStart;
int rightTreeCount = inEnd - rootIndex;
root->left = helper(inorder, inStart, rootIndex - 1, postorder, postStart, postStart + leftTreeCount - 1);
root->right = helper(inorder, rootIndex + 1, inEnd, postorder, postEnd - rightTreeCount, postEnd - 1);
return root;
}
};
二刷:
/**
* 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:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return helper(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1);
}
private:
TreeNode* helper(vector<int>& inorder, int inStart, int inEnd, vector<int>& postorder, int postStart, int postEnd) {
if (inStart > inEnd || postStart > postEnd) return NULL;
int rootValue = postorder[postEnd];
TreeNode *root = new TreeNode(rootValue);
if (inStart == inEnd || postStart == postEnd) return root;
int rootIndex = inStart;
for (int i = inStart; i <= inEnd; i++) {
if (inorder[i] == rootValue) {
rootIndex = i;
break;
}
}
int leftNodeNum = rootIndex - inStart, rightNodeNum = inEnd - rootIndex;
// cout << "leftNodeNum=" << leftNodeNum << " rightNodeNum=" << rightNodeNum << endl;
if (leftNodeNum > 0) {
root->left = helper(inorder, inStart, rootIndex - 1, postorder, postStart, postStart + leftNodeNum - 1);
}
if (rightNodeNum > 0) {
root->right = helper(inorder, rootIndex + 1, inEnd, postorder, postStart + leftNodeNum, postEnd - 1);
}
return root;
}
};
三刷:用一个map把inorder的num和index保存下来,用来得到leftSize。
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
int n = inorder.size(), n2 = postorder.size();
if (n == 0 || n != n2) return NULL;
for (int i = 0; i < n; i++) um[inorder[i]] = i;
return helper(inorder, 0, n - 1, postorder, 0, n - 1);
}
private:
unordered_map<int, int> um; //<num, index in inodrder>
TreeNode *helper(vector<int>& inorder, int start1, int end1, vector<int>& postorder, int start2, int end2) {
if (start1 > end1) return NULL;
// if (start1 == end1) return new TreeNode(inorder[start1]);
int pos = um[postorder[end2]];
int leftSize = pos - start1;
TreeNode *root = new TreeNode(postorder[end2]);
root->left = helper(inorder, start1, pos - 1, postorder, start2, start2 + leftSize - 1);
root->right = helper(inorder, pos + 1, end1, postorder, start2 + leftSize, end2 - 1);
return root;
}
};
本文介绍了一种算法,该算法利用给定的中序和后序遍历序列来构建二叉树。通过解析后序遍历的最后一个元素作为根节点,并在中序遍历中定位该节点,可以递归地构建左子树和右子树。文章提供了详细的C++代码实现,包括使用映射优化查找过程的方法。
781

被折叠的 条评论
为什么被折叠?



