• [leetCode]07.重建二叉树


    在这里插入图片描述

    递归

    前序遍历为:| 根结点 | 左子树 | 右子树 |
    中序遍历为:| 左子树 | 根结点 | 右子树 |

    以前序遍历中的根节点到中序遍历中寻找根节点,这样就能知道左右子树的长度。左右子树有符合相同的查找模式,所以可以使用递归。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder.length == 0 || inorder.length == 0)
                    return null;
            int startPreorder = 0, endPreorder = preorder.length - 1;
            int startInorder = 0, endInorder = inorder.length - 1;
            return reconstructTree(
                preorder,
                startPreorder,
                endPreorder,
                inorder,
                startInorder,
                endInorder);
        }
    
        private TreeNode reconstructTree(
            int[] preorder,
            int startPreorder, 
            int endPreorder,
            int[] inorder,
            int startInorder,
            int endInorder){
                int rootVal = preorder[startPreorder];
                TreeNode root = new TreeNode(rootVal);
                if(startPreorder == endPreorder){
                    return root;
                }
                int rootInorder = 0;    
                while(rootInorder <= endInorder && inorder[rootInorder] != rootVal){
                    ++rootInorder;
                }
                if(inorder[rootInorder] != rootVal){
                    throw new RuntimeException("input error");
                }
                int leftNodeNums = rootInorder - startInorder;
                int leftPreoderEnd = startPreorder + leftNodeNums;
                if(leftNodeNums > 0){
                    root.left = reconstructTree(
                            preorder,
                            startPreorder+1,
                            leftPreoderEnd,
                            inorder,
                            startInorder,
                            rootInorder-1);
                }
                if(leftNodeNums < endPreorder - startPreorder){
                     root.right = reconstructTree(
                            preorder,
                            leftPreoderEnd+1,
                            endPreorder,
                            inorder,
                            rootInorder+1,
                            endInorder);
                }
                return root;
            }
    } 
    

    上面的代码使用了指针。可以通过哈希表记录中序遍历中根结点的索引,这样就能快速找到前序遍历中的根结点在中序遍历的位置

    class Solution {
        HashMap<Integer,Integer> map;//记录中序遍历中的结点下标
        int[] preorder_copy;
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder.length == 0 || inorder.length == 0)
                    return null;
            //初始化map用于快速查询根节点下标
            map = new HashMap<>();
            for(int i = 0; i < inorder.length; i++){
                map.put(inorder[i],i);
            }
            preorder_copy = preorder;
            return rebuild(0 ,0, inorder.length - 1);
        }
    
        private TreeNode rebuild(int preRoot, int inLeft, int inRight){
            if(inLeft > inRight) return null;
            TreeNode root = new TreeNode(preorder_copy[preRoot]);
            int i = map.get(preorder_copy[preRoot]);
            root.left = rebuild(preRoot+1,inLeft,i-1);
            root.right = rebuild(preRoot + i - inLeft + 1,i+1,inRight);
            return root;
        }
    }
    

    迭代

    leetCode官方题解

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
    
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder.length == 0 || inorder.length == 0)
                    return null;
            TreeNode root  = new TreeNode(preorder[0]);
            LinkedList<TreeNode> stack = new LinkedList<>();
            stack.push(root);
            int index = 0;
            for(int i = 1; i < preorder.length; i++){
                int nextRootVal = preorder[i];//下一个结点的值
                TreeNode node = stack.peek();//上一个结点
                if(node.val != inorder[index]){
                    node.left = new TreeNode(nextRootVal);
                    stack.push(node.left);
                }else {
                    while(!stack.isEmpty() && stack.peek().val == inorder[index]){
                       ++index;
                       node = stack.pop();
                    }
                    node.right = new TreeNode(nextRootVal);
                    stack.push(node.right);
                }
            }
            return root;
        }
    
    }
    
  • 相关阅读:
    恢复 root 本地无权限 Access denied for user 'root'@'localhost' (using password: NO)
    linux 下 PHP Notice: session_start(): ps_files_cleanup_dir 报错 问题剖析
    linux 下mysql 开启远程连接
    linux 下mysql 字段插入的值超过 预设大小报错
    CSS、HTML5、JS
    WPF、Sivelright、UWP
    Quartz.net作业调度
    nginx+iis、NLB、Web Farm、Web Garden、ARR
    workflow
    SqlSugar ORM
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13859985.html
Copyright © 2020-2023  润新知