来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
给定一棵树的前序遍历 preorder 与中序遍历 inorder。请构造二叉树并返回其根节点。
示例 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]
提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均无重复元素
inorder 均出现在 preorder
preorder 保证为二叉树的前序遍历序列
inorder 保证为二叉树的中序遍历序列
思路:前序遍历是根左右,中序遍历是左根右,所以前序遍历第一个一定是根,我们可以在中序遍历找到这个根,并一分为二,左边是左子树,右边是右子树,这样能建成一个根。左子树,右子树暂时不清楚具体,但是长度能确定。所以前序遍历除去根后也能一分为二。左子树的数字正好与中序遍历形成了相对应的长度。这样一个大问题就变成了一个小问题。这样再继续划分,直到最后一个,然后回溯的过程就建成了一棵树,直接输出即可。
/**
* Definition for a binary tree node.
* 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:
int length;
TreeNode* dfs(vector<int>&preorder, vector<int>& inorder, int pl, int pr, int il, int ir)
{
int i, shu, wei, chang;
/*if (preorder.size() < 1) return nullptr;不可以,因为vector数组永远不变的
if (inorder.size() < 1) return nullptr;
if (pl >= length) return nullptr;*/
if (pl > pr) return nullptr;
if (il > ir) return nullptr;
shu = preorder[pl];
for (i = il; i <= ir; i++){
if (inorder[i] == shu){
wei = i;//根节点在中序遍历中的位置
}
}
chang = wei - il;
TreeNode* root1 = new TreeNode(shu);//这个数作为根节点建立一棵树
root1->left = dfs(preorder, inorder, pl + 1, pl + chang, il, wei - 1);
root1->right = dfs(preorder, inorder, pl + chang + 1, pr, wei + 1, ir);
return root1;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
length = preorder.size();
return dfs(preorder, inorder, 0, length - 1, 0, length - 1);//后面的是用来记录当前的树是什么样子的,即边界
}
};