【剑指offer07】【C++】重建二叉树

38 篇文章 0 订阅

【剑指offer07】【C++】重建二叉树

题目

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

      3
     /  \
    9   20
   /      \
  15       7

限制:
0 <= 节点个数 <= 5000

题解

笔记:

递归思想,最重要的是找到前序遍历和中序遍历中的左子树和右子树的起始下标和终止下标(左子树为s1,e1,右子树为s2,e2)
	1.判断s1,e1,s2,e2是否越界
		1.1 先根据前序遍历找到root的下标,其实就是第一个preorder[s1];
		1.2 根据root的val找到根节点在中序遍历的下标i
		1.3 那么在下一次的递归中,传入的新参数,易求的有:
			root->left左子树的前序遍历下标(s1+1,?),中序遍历下标(s2,i-1)
			root->right右子树的前序遍历下标(?+1,e1),中序遍历下标(i+1,e2)
		1.4那么仅需要把“?”求出来,“?”是什么呢,其实就是s1+左子树的节点个数=左子树结束节点的位置下标
			事实上节点个数在中序遍历中可求得,(i-1)-s2+1=i-s2;那么在前序遍历中,左子树和右子树刚好分开处  的  左子树结束节点的位置即为s1+i-s2="?",所以右子树前序遍历下标即为((s1+i-s2)+1,e1).

代码:

/**
 * 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* construct(vector<int>& preorder, vector<int>& inorder,int s1,int e1,int s2,int e2){
        if(s1<=e1&&s2<=e2){
            int rootval = preorder[s1];
            TreeNode* tree = new TreeNode(rootval);
            for(int i=s2;i<=e2;i++)
            {
                if(rootval==inorder[i]){
                    tree->left = construct(preorder,inorder,s1+1,s1+i-s2,s2,i-1);
                    tree->right = construct(preorder,inorder,s1+i-s2+1,e1,i+1,e2);
                }
            }
            return tree;
        }
        return nullptr;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return construct(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值