剑指offer-刷题笔记-中难题-JZ7 重建二叉树

剑指offer-刷题笔记-中难题-JZ7 重建二叉树

注意:通过先序遍历和中序遍历可以确定二叉树, 通过中序遍历和后续遍历可以唯一确定二叉树,通过先序遍历和后序遍历确定不了二叉树。

1.通过先序遍历和中序遍历可以确定二叉树

算法:

1.通过先序遍历找到根节点A,再通过根节点在中序遍历的位置找出左子树,右子树
2.在A的左子树中,找出左子树的根节点(先序遍历),递归进入1
3.在A的右子树中,找出右子树的根节点(先序遍历),递归进入1

输入输出

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        int n = pre.size();
        int m = vin.size();
        //两个遍历都不能为0
        if(n==0||m==0)
        {
            return nullptr; 
        }
        //构建根节点
        TreeNode *root = new TreeNode(pre[0]);
        for(int i = 0;i<vin.size();i++)
        {
            //找到中序遍历中的前序第一个元素
            if(pre[0] == vin[i])
            {
                //输入pre{1,2,4,7,3,5,6,8},vin{4,7,2,1,5,3,8,6}
                //满足条件i=3, 左子树前序遍历{2,4,7},
                //左子树的前序遍历
                vector<int> leftpre(pre.begin() + 1, pre.begin() + i + 1);//注意尾指针指到后面一个
                //左子树的中序遍历
                vector<int> leftvin(vin.begin(),vin.begin()+i);
                //构建左子树
                root->left = reConstructBinaryTree(leftpre,leftvin);
                //右子树的前序遍历
                vector<int> rightpre(pre.begin()+i+1, pre.end());
                //右子树的中序遍历
                vector<int> rightvin(vin.begin()+i+1,vin.end());
                root->right = reConstructBinaryTree(rightpre, rightvin);
                break;
            }
        }   
        return root; 
    }
};

2.通过中序遍历和后序遍历可以确定二叉树

算法:

1.通过后序遍历找到根节点A,再通过根节点在中序遍历的位置找出左子树,右子树
2.在A的左子树中,找出左子树的根节点(后序遍历),递归进入1
3.在A的右子树中,找出右子树的根节点(后序遍历),递归进入1

输入输出

class Solution {
public:
    
    TreeNode* reConstructBinaryTree(vector<int> post,vector<int> vin) {
        int n = post.size();
        int m = vin.size();
        //两个遍历都不能为0
        if(n==0||m==0)
        {
            return nullptr; 
        }
        //构建根节点
        TreeNode *root = new TreeNode(post[post.size()-1]);
        for(int i = 0;i<vin.size();i++)
        {
            //找到中序遍历中的后序最后一个元素
            if(post[post.size()-1] == vin[i])
            {
                //输入post{7,4,2,5,8,6,3,1},vin{4,7,2,1,5,3,8,6}
                //满足条件i=3, 左子树后序遍历{7,4,2},
                //左子树的后序遍历
                vector<int> leftpost(post.begin(), post.begin() + i);//注意尾指针指到后面一个
                //左子树的中序遍历
                vector<int> leftvin(vin.begin(),vin.begin()+i);
                //构建左子树,
                root->left = reConstructBinaryTree(leftpost,leftvin);
                //右子树的后序遍历
                vector<int> rightpost(post.begin()+i, post.end()-1);
                //右子树的中序遍历
                vector<int> rightvin(vin.begin()+i+1,vin.end());
                root->right = reConstructBinaryTree(rightpost, rightvin);
                break;
            }
        }   
        return root; 
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值