剑指 Offer 07. 重建二叉树
难度中等
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
限制:
0 <= 节点个数 <= 5000
思路:
(1)前序遍历确定访问顺序,中序遍历决定左右子树成员
(2)每个节点的构造在两个遍历序列都有选值范围
1. 根节点的选值范围是全部,根节点在inorder的位置是index,根节点在preorder的位置是 0
2. 由此得出index左侧,即范围inorder[Instart,index)构成当前节点的左子树
3. index右侧,即范围inorder[index+1,Inend)构成右子树
4. 所以preorder[preStart+1,preStart+1 + index-inStart)构成左子树
5. preorder[preStart+1 + index-inStart,preEnd)构成右子树
终止条件:
- InStart == InEnd || preStart == preEnd
代码:
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) {
TreeNode* rst = buildNode(preorder, 0, preorder.size(), inorder, 0, inorder.size());
return rst;
}
TreeNode* buildNode(vector<int>& preorder,int preStart,int preEnd,
vector<int>& inorder,int inStart,int inEnd){
if (inStart == inEnd || preStart == preEnd) return NULL;
TreeNode* newNode = new TreeNode(preorder[preStart]);
int index;
for (int i = inStart; i < inEnd; ++i) {
if (inorder[i] == preorder[preStart]) index = i;
}
newNode->left = buildNode(preorder, preStart + 1, preStart + 1 + (index - inStart),
inorder, inStart, index);
newNode->right = buildNode(preorder, preStart + 1 + (index - inStart), preEnd,
inorder, index + 1, inEnd);
return newNode;
}
};