剑指 Offer 07. 重建二叉树
难度:中等
题意
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
限制:
0 <= 节点个数 <= 5000
解题思路
前序遍历的顺序为:根左右,中序遍历的顺序为:左根右,那么也就可以知道每一个vector对象preorder的preorder[0]都是目前遍历的这个子树的根,因为这个二叉树的每个值都不重复,所以,也就可以根据这个preorder[0]把中序遍历的inorder分出左右子树和根,只要我们在中序遍历中定位到根节点,那么我们就可以分别知道左子树和右子树中的节点数目。由于同一颗子树的前序遍历和中序遍历的长度显然是相同的,因此我们就可以对应到前序遍历的结果中,对左右子树进行定位。
C++解法
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() == 0 || inorder.size() == 0) return NULL;
int flag = preorder[0];
int index = 0;
for(int i = 0; i < inorder.size(); i++) {
if(inorder[i] == flag) {
index = i;
break;
}
}
TreeNode *root = new TreeNode(flag);
vector<int> a(preorder.begin() + 1, preorder.begin() + index + 1);
vector<int> b(inorder.begin(), inorder.begin() + index);
vector<int> c(preorder.begin() + index + 1, preorder.end());
vector<int> d(inorder.begin() + index + 1, inorder.end());
root -> left = buildTree(a, b);
root -> right = buildTree(c, d);
return root;
}
};