[Leetcode] Construct Binary Tree from Preorder and Inorder Traversal
Construct Binary Tree from Preorder and Inorder Traversal 题解
题目来源:https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/
Description
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
Example
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
Solution
class Solution {
private:
void recursiveBuild(TreeNode* &node, vector<int>& preorder, int pstart, int pend,
vector<int>& inorder, int istart, int iend) {
if (pstart > pend)
return;
node = new TreeNode(preorder[pstart]);
if (pstart == pend)
return;
int i;
for (i = istart; i <= iend; i++)
if (inorder[i] == preorder[pstart])
break;
recursiveBuild(node -> left,
preorder, pstart + 1, pstart + i - istart,
inorder, istart, i - 1);
recursiveBuild(node -> right,
preorder, pstart + i - istart + 1, pend,
inorder, i + 1, iend);
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.empty() || inorder.empty())
return NULL;
TreeNode *root;
recursiveBuild(root, preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1);
return root;
}
};
解题描述
这道题是经典的通过二叉树的前序遍历和中序遍历来还原二叉树的问题。上面给出的是递归的做法。基本的思想是,前序遍历的第一个点即是当前子树的根节点,在中序遍历中找到这个点,这个点左边的元素就属于左子树,右边的元素就属于右子树,根据中序遍历中左右子树的规模可以在前序遍历中分别找到左右子树的前序遍历序列,这样递归查找下去就可以还原整棵树。
当然了,这道题还可以用迭代的方法来解决,具体使用队列来模拟递归顺序:
class Solution {
private:
struct Task {
TreeNode** nodep;
int pstart, pend, istart, iend;
Task(TreeNode** p, int ps, int pe, int is, int ie) :
nodep(p), pstart(ps), pend(pe), istart(is), iend(ie) {}
};
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.empty() || inorder.empty())
return NULL;
TreeNode *root;
int pstart, pend, istart, iend, i;
queue<Task> q;
q.push(Task(&root, 0, preorder.size() - 1, 0, inorder.size() - 1));
while (!q.empty()) {
Task task = q.front();
q.pop();
pstart = task.pstart;
pend = task.pend;
istart = task.istart;
iend = task.iend;
if (pstart > pend)
continue;
TreeNode* node = new TreeNode(preorder[pstart]);
*(task.nodep) = node;
if (pstart == pend)
continue;
for (i = istart; i <= iend; i++)
if (inorder[i] == preorder[pstart])
break;
q.push(Task(&(node -> left), pstart + 1, pstart + i - istart, istart, i - 1));
q.push(Task(&(node -> right), pstart + i - istart + 1, pend, i + 1, iend));
}
return root;
}
};