Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
For example, given
preorder = [3,9,20,15,7] inorder = [9,3,15,20,7]
Return the following binary tree:
3 / \ 9 20 / \ 15 7
思路:
通过递归的方式构造二叉树。两种实现方式,最后解释差异:
1 直接拷贝
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.size() == 0) return NULL;
int val = preorder[0];
int left = 0;
while (inorder[left] != val) left++;
TreeNode *root = new TreeNode(val);
vector<int> preorderLeft(preorder.begin()+1, preorder.begin() + left+1);
vector<int> inorderLeft(inorder.begin(), inorder.begin() + left);
root->left = buildTree(preorderLeft, inorderLeft);
vector<int> preorderRight(preorder.begin() + left+1, preorder.end());
vector<int> inorderRight(inorder.begin() + left+1, inorder.end());
root->right = buildTree(preorderRight, inorderRight);
return root;
}
2 跟踪标号
TreeNode* buildTree2(vector<int>& preorder, vector<int>& inorder, vector<int> p){
if (p[0] < 0 || p[2] < 0 || p[1] < p[0] || p[3] < p[2] || p[0] >= preorder.size() || p[2] >= inorder.size())
return NULL;
int val = preorder[p[0]];
int left = p[2];
while (inorder[left] != val) left++;
TreeNode *root = new TreeNode(val);
vector<int> pLeft = p;
pLeft[0]++;
pLeft[1] = p[0]+left-p[2];
pLeft[3] = left-1;
root->left = buildTree2(preorder, inorder, pLeft);
vector<int> pRight = p;
pRight[0] += left-p[2] + 1;
pRight[2] = left + 1;
root->right = buildTree2(preorder, inorder, pRight);
return root;
}
TreeNode* buildTree2(vector<int>& preorder, vector<int>& inorder){
vector<int> p;
p.push_back(0);
p.push_back(preorder.size() - 1);
p.push_back(0);
p.push_back(inorder.size() - 1);
return buildTree2(preorder, inorder, p);
}
可以看到,第一种方式简单直观,但是中间有很多赋值操作,会大量增加运行时间和内存使用,第二种使用索引的方式来构造二叉树,虽然逻辑繁琐一点(我已经晕了,所以第一个判断我就快刀斩乱麻,想到什么加什么了),但是运行时间较快,消耗内存少。