zoukankan      html  css  js  c++  java
  • 二叉树--前中后序两两结合构建二叉树

    题解

    1. 你可以假设树中没有重复的元素。这句话代表什么呢?

    这样可以保证结点的数值可以在中序遍历数组中唯一确定,这样还原出的二叉树是唯一确定的

    1. 根据(先序+中序)或者(中序+后序)可以唯一确定二叉树,根据(先序+后序)无法唯一确定二叉树,但是如果一棵二叉树除了叶子结点外,其他所有结点都有左子和右子,这样的树可以根据(先序+后序)唯一确定。

    先序+中序确定二叉树(leetcode 105)

    思路

    1. 先序数组中最左边的值就是树的根节点的值,记为h,并用h生成头节点,记为head。然后在中序数组找到h,设位置为i。在中序数组中,i左边的数组就是头节点左子树的中序数组,假设长度为l,则左子树的先序数组就是先序数组中h往右长度为l的数组。

    2. 用左子树的先序和中序数组,递归构建左子树,返回的头节点为left

    3. i右边的数组就是头节点右子树的中序数组,假设长度为r。先序数组中右侧等长的部分就是头节点右子树的先序数组

    4. 用右子树的先序和中序数组,递归构建右子树,返回的右节点记为right

    5. 将head的左子,右子设为left,right,返回head,过程结束。

    在中序数组中找到位置i可以用哈希表实现。

    时间复杂度:O(n)
    空间复杂度:O(n)

    代码

        public TreeNode buildTree(int[] preorder, int[] inorder) {
            int preLen = preorder.length;
            int inLen = inorder.length;
            if (preLen != inLen){
                throw new RuntimeException("Error");
            }
    
            Map<Integer, Integer> map = new HashMap<>();
            for (int i = 0; i < inLen; i++){
                map.put(inorder[i], i);
            }
    
            return helper(preorder, 0, preLen - 1, inorder, 0, inLen - 1, map);
        }
    
        public TreeNode helper(int[] preorder, int preLeft, int preRight,
                               int[] inorder, int inLeft, int inRight,
                               Map<Integer, Integer> map){
            if (preLeft > preRight || inLeft > inRight){
                return null;
            }
            int rootVal = preorder[preLeft];
            TreeNode root = new TreeNode(rootVal);
            int index = map.get(rootVal);
    
            root.left = helper(preorder, preLeft + 1, index - inLeft + preLeft,
                                inorder, inLeft, index - 1, map);
            root.right = helper(preorder, index - inLeft + preLeft + 1, preRight,
                                inorder, index + 1, inRight, map);
            return root;
        }
    

    后序+中序确定二叉树(leetcode 106)

    和第一种类似,后序数组中头节点是后序数组最右的值,用后序最右的值划分中序数组即可。时空间复杂度也和之前的一样。

        public TreeNode buildTree(int[] inorder, int[] postorder) {
            int inLen = inorder.length;
            int posLen = postorder.length;
            if (inLen != posLen){
                throw new RuntimeException("Error!");
            }
            Map<Integer, Integer> map = new HashMap<> ();
            for (int i = 0; i < inLen; i++) {
                map.put(inorder[i], i);
            }
            return helper(inorder, 0, inLen - 1, postorder, 0, posLen - 1, map);
        }
        
        public TreeNode helper(int[] inorder, int inLeft, int inRight,
                               int[] postorder, int postLeft, int postRight,
                               Map<Integer, Integer> map){
            if (inLeft > inRight || postLeft > postRight){
                return null;
            }
            int rootVal = postorder[postRight];
            TreeNode root = new TreeNode(rootVal);
            int index = map.get(rootVal);
            root.left = helper(inorder, inLeft, index - 1,
                                postorder, postLeft, postLeft + index - inLeft - 1,
                                map);
            root.right = helper(inorder, index + 1, inRight,
                                postorder, postLeft + index - inLeft, postRight - 1,
                                map);
            return root;
        }
    

    先序+后序构建二叉树(leetcode 889)

    待施工

  • 相关阅读:
    【Luogu】P3369 【模板】普通平衡树(树状数组)
    文艺平衡树 lg3391(splay维护区间入门)
    普通平衡树 lg3369
    noip2018游记
    webview与壳交互的几种方式
    iOS、Android 之类的如何调试 Web APP
    box-sizing属性
    Hybridapp /webapp调试工具
    DOS 批处理高级教程精选合编
    瀑布流Masonry学习
  • 原文地址:https://www.cnblogs.com/swifthao/p/13340691.html
Copyright © 2011-2022 走看看