leetcode-重建二叉树

刷leetcode《剑指offer》中第七题“重建二叉树”,以下记录一下解题思路。

题目

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
给出以下的前序以及中序遍历结果

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:
    3
   / \
  9  20
    /  \
   15   7

解析

  1. 前序遍历的首个元素即为根节点 root 的值;

  2. 在中序遍历中搜索根节点 root 的索引 ,可将中序遍历划分为[ 左子树 | 根节点 | 右子树 ]

  3. 根据中序遍历中的左(右)子树的节点数量,可将前序遍历划分为 [ 根节点 | 左子树 | 右子树 ]

  4. 根据前序以及中序可以知道,根节点肯定是前序遍历的第一个节点。由根节点可以找到中序遍历的位置,从而可以构建其左子树、右子树。由图可以知道,使用分治法思想,将其划分为每个小部分,进行递归。

    di9N59.png

注意

题目的重点部分来源于对递归的条件以及递归的参数的取舍。

  1. 递归的条件(当左边大于右边就会越界,就证明没有节点)

     if (preL > preR || inoL > inoR) {
         return null;
      }
  2. 递归参数取舍

    解决: 取1在中序遍历的位置为pivot,设9的位置为x,可列x - (preL+1)=pivot-1-inL,可以得到9的位置,从而使用分治算法,切割左右子树。

     // 构建左子树
     root.left = buildTree(preL + 1, index - inoL + preL, inoL, index - 1);
     // 构建右子树
     root.right = buildTree(index - inoL + preL + 1, preR, index + 1, inoR);

具体实现代码

/**
 * 重建二叉树,有前序遍历结果以及中序遍历结果
 *    3
 *    / \
 *   9  20
 *     /  \
 *    15   7
 */
class Solution {

    // 利用空间换时间
    HashMap map = new HashMap();
    int[] pre;

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int preL = preorder.length;
        int inoL = inorder.length;
        pre = preorder;
        // 将中序遍历存入map中
        for (int i = 0; i < inoL; i++) {
            map.put(inorder[i], i);
        }
        return buildTree(0, preL - 1, 0, inoL - 1);
    }

    /**
     * @param preL 前序遍历左端
     * @param preR 前序遍历右端
     * @param inoL 中序遍历左端
     * @param inoR 中序遍历右端
     * @return
     */
    private TreeNode buildTree(int preL, int preR, int inoL, int inoR) {
        if (preL > preR || inoL > inoR) {
            return null;
        }
        // 构建二叉树的根节点,必须是前序遍历的第一个节点
        TreeNode root = new TreeNode(pre[preL]);
        // 找到根节点在中序遍历的位置
        int index = (int) map.get(pre[preL]);
        // 构建左子树
        root.left = buildTree(preL + 1, index - inoL + preL, inoL, index - 1);
        // 构建右子树
        root.right = buildTree(index - inoL + preL + 1, preR, index + 1, inoR);
        return root;
    }
}
全部评论

相关推荐

评论
点赞
收藏
分享
牛客网
牛客企业服务