剑指 Offer 07. 重建二叉树

本文解析了如何利用前序遍历和中序遍历构建二叉树,通过理解节点关系,找到根节点的左边界并构造右子树。关键在于找到前序序列中的'中'元素,以此划分左右子树。

题目来源

leetcode 剑指 Offer

分析

原则:

  • 前序遍历是从最顶层根节点开始,中序遍历是从最底层左节点开始的。
  • 前序遍历得到根节点,中序遍历由前序遍历得到的根节点分为左右子树。
  • 假如从树的根节点开始,遍历前序序列直到与中序序列中的第一个元素相等时,遍历得到的节点都为该根节点的最左侧所有节点。
  • 之后从最底层开始遍历子树的根节点得到其右子树。

总结:

  • 前序遍历: 中、左1、左2、…、左n-1、左n、右n。
  • 中序遍历: 左n、左n-1、右n、…、左1、中、右。
  • 根据前序序列与中序序列的遍历关系,可以很容易得到根节点的最左侧所有节点,接着再反向遍历得到的最左侧节点(使用栈),得到左节点为根节点的子树的右节点。
  • 关键点:中、左n。
  • 先使用前序遍历得到根节点的最左侧子节点,再根据中序序列从前序遍历中得到子树右节点。
  • 前序遍历得到节点集,中序遍历改变关注的子树对象。

代码:

使用递归(略)。

使用迭代:

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder == null || preorder.length == 0){
            return null;
        }
        // 用来存放遍历的前序序列节点的栈,深度优先原理,即后进先出
       Stack<TreeNode> stack = new Stack<TreeNode>();
       TreeNode root = new TreeNode(preorder[0]); 
       stack.push(root);
       int indexInorder = 0;
       TreeNode node;
       // 遍历前序序列
       for(int i=1; i<preorder.length; i++){
           node = stack.peek(); // 遍历栈顶元素
           // 判断遍历到的前序序列元素是否与当前中序序列的元素相等
           if(node.val != inorder[indexInorder]){  // 不相等
               node.left = new TreeNode(preorder[i]);
               stack.push(node.left);
           }else{  
                // 相等,说明是子树根节点
                while(!stack.isEmpty() && stack.peek().val == inorder[indexInorder]){
                    node = stack.pop();
                    indexInorder++;
                }
                // 构造树的右子树
                node.right = new TreeNode(preorder[i]);
                stack.push(node.right);
           }
       }
       return root;
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值