给定一棵树的前序遍历preorder
与中序遍历inorder
。请构造二叉树并返回其根结点。
示例:
输入:preorder = [3, 9, 20, 15, 7], inorder = [9, 3, 15, 20, 7]
输出:[3, 9, 20, null, null, 15, 7]
思路:
构建二叉树采用前序构建的方式:
- 构建根结点。
- 构建左子树。
- 构建右子树。
根据所给前序遍历序列,我们可以依次获得所需构建子树的根结点值,在构建某一子树时,我们可以找出该子树根结点在其中序遍历序列当中的位置,进而将该子树的中序遍历序列划分为其左子树和右子树的中序遍历序列,从而进行后续其左右子树的构建。
代码如下:
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>& preorder, int& pi, vector<int>& inorder, int inStart, int inEnd)
{
if (inStart > inEnd) //中序序列不存在,该子树是空树
return nullptr;
//1、构建该子树的根结点
TreeNode* root = new TreeNode(preorder[pi]);
pi++;
//2、将该子树的中序遍历序列划分为其左子树和右子树的中序遍历序列
int rooti = inStart;
while (inorder[rooti] != root->val)
{
rooti++;
}
//3、递归构建该子树的左右子树
root->left = _buildTree(preorder, pi, inorder, inStart, rooti - 1);
root->right = _buildTree(preorder, pi, inorder, rooti + 1, inEnd);
//4、返回所构建子树的根
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int i = 0; //标识当前构建子树的根结点在preorder当中的下标
return _buildTree(preorder, i, inorder, 0, inorder.size() - 1);
}
};