【剑指Offer 07.重建二叉树】题解分享

重建二叉树 迭代算法题解

回顾题目:力扣(LeetCode)
链接:https://leetcode.cn/problems/zhong-jian-er-cha-shu-lcof

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

示例 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]

限制:

0 <= 节点个数 <= 5000

题目给出的二叉树结构如下

  struct TreeNode {
      int val;
      TreeNode *left;
      TreeNode *right;
      TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  };

前置知识:

前序遍历:根结点 —> 左子树 —> 右子树

中序遍历:左子树—> 根结点 —> 右子树

迭代算法思路:

1.从前序和中序遍历的顺序中可以看出,如果有这样一个二叉树只有左子树,没有右子树,则前序遍历和中序遍历的结果将恰好相反。且中序遍历到的第一个数表示的是这个二叉树的最左下角的位置,而前序遍历从根节点开始,先一直遍历左子节点,直到遍历到最左下角再开始遍历右子节点。
2.用一个index指针指向中序遍历的第一个值,用一个栈来维护当前节点,先按照前序遍历将所有纯左子节点依次入栈,直至入栈的左子节点的值与中序遍历的第一个值相等,说明已经遍历至最左下角,将此时栈顶的值与index指针指向的中序遍历值相比较,如果相等则index指针加一,指向下一个中序遍历的值,栈顶节点弹出;如果不相等则说明index所指的值是一个右子节点的值,而这个右子节点的父节点就是当前栈顶的节点。

题解代码+注释

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size()==0)return nullptr;//空树判断
        TreeNode* root=new TreeNode(preorder[0]);//创建二叉树的根节点
        stack<TreeNode*> stk;//建立stk栈用于维护逆序的左子树节点
        stk.push(root);//根节点入栈
        int index=0;//建立index指针用于遍历中序的值
        for(int i=1;i<preorder.size();++i){
            int preorderVal = preorder[i];
            TreeNode* node=stk.top();//设置node为当前栈顶节点
            if(node->val!=inorder[index]){//如果当前栈顶节点值不等于中序遍历的首值,说明stk栈还未到达二叉树的最左下角
                node->left=new TreeNode(preorderVal);
                stk.push(node->left);//新建的左子节点入栈
            }else{
                while(!stk.empty()&&stk.top()->val==inorder[index]){//若当前栈顶节点与inorder的值相等,则说明当前栈顶节点没有右子节点
                    node=stk.top();
                    stk.pop();
                    ++index;
                }
                node->right=new TreeNode(preorderVal);//若不相等,则inorder[index]即为当前栈顶节点的右节点
                stk.push(node->right);//新建的右子节点入栈
            }
        }
        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

启立家的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值