二叉树的构造

今天来谈二叉树的构造,主要有以下几个问题:

  1. 最大二叉树
  2. 前序和中序构造二叉树
  3. 后序和中序构造二叉树
  4. 前序和后序构造二叉树

二叉树构造模板,分治模式:

构造整棵树 = 根节点 + 构造左子树 + 构造右子树

一、最大二叉树

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return build(nums, 0, nums.length-1);
    }
    //根据数组构造一个树,需要知道数组的本身和用到数组哪一部分
    TreeNode build(int[] nums, int left, int right) {
        if(left > right) return null;
        //寻找最大值以及对应的索引,最大值用来构造根节点,索引用来构造子树
        int index = -1; int max = Integer.MIN_VALUE;
        for(int i=left; i<=right; i++) {
            if(nums[i] > max) {
                index = i;
                max = nums[i];
            }
        }
        //构造根节点
        TreeNode root = new TreeNode(max);
        //构造左右子树
        root.left = build(nums, left, index-1);
        root.right = build(nums, index+1, right);
        return root;
    }
}

二、前序和中序构造二叉树

class Solution {
    Map<Integer,Integer> valToIndex = new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        for(int i=0; i<inorder.length; i++) {
            valToIndex.put(inorder[i],i);
        }
        return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
    }
    TreeNode build(int[] preorder, int preleft, int preright, int[] inorder, int inleft, int inright) {
        //终止条件
        if(preleft > preright || inleft > inright) return null;
        //找到中序遍历的根节点及其对应的索引
        int rootVal = preorder[preleft];
        int index = valToIndex.get(rootVal);
        int leftSize = index - inleft;
        //构造二叉树
        TreeNode root = new TreeNode(rootVal);
        root.left = build(preorder,preleft+1,preleft+leftSize,inorder,inleft,index-1);
        root.right = build(preorder,preleft+leftSize+1,preright,inorder,index+1,inright);
        return root;
        
    }
}

三、后序和中序构造二叉树

class Solution {
    Map<Integer,Integer> valToIndex = new HashMap<>();
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for(int i=0; i<inorder.length; i++) {
            valToIndex.put(inorder[i],i);
        }
        return build(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
    }
    TreeNode build(int[] inorder, int inleft, int inright, int[] postorder, int postleft, int postright) {
        //终止条件
        if(inleft > inright || postleft > postright) return null;
        //找到中序遍历的根节点及其对应的索引
        int rootVal = postorder[postright];
        int index = valToIndex.get(rootVal);
        int leftSize = index - inleft;
        //构造二叉树
        TreeNode root = new TreeNode(rootVal);
        root.left = build(inorder,inleft,index-1,postorder,postleft,postleft+leftSize-1);
        root.right = build(inorder,index+1,inright,postorder,postleft+leftSize,postright-1);
        return root;
        
    }
}

四、前序和后序构造二叉树

class Solution {
    Map<Integer,Integer> valToIndex = new HashMap<>();
    public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
        for(int i=0; i<postorder.length-1; i++) {
            valToIndex.put(postorder[i],i);
        }
        return build(preorder,0,preorder.length-1,postorder,0,postorder.length-1);
    }
    TreeNode build(int[] preorder, int preleft, int preright, int[] postorder, int postleft, int postright) {
        if(preleft > preright) return null;
        //一定要加这一句
        if(preleft == preright) return new TreeNode(preorder[preleft]);
        int rootVal = preorder[preleft];
        //这里假设左子树根节点存在,其实也可以不存在,所以导致前+后构造的二叉树不唯一
        int leftRootVal = preorder[preleft+1];
        int index = valToIndex.get(leftRootVal);
        int leftSize = index-postleft+1;
        TreeNode root = new TreeNode(rootVal);
        root.left = build(preorder,preleft+1,preleft+leftSize,postorder,postleft,index);
        root.right = build(preorder,preleft+leftSize+1,preright,postorder,index+1,postright-1);
        return root;
    }
}

总结

  1. 根据前序和中序或者后序和中序构造二叉树三步走:(1)left>right 终止 (2)寻找根节点及其索引 (3)构造根节点、左右子树
  2. 根据前序和后序构造二叉树三步走:(1)left>right 终止 (2)left == right 返回新的根节点 (3)寻找根节点、左子树根节点及其索引 (3)构造根节点、左右子树

题目链接

leetcode-654:最大二叉树
leetcode-105:从前序和中序遍历构造二叉树
leetcode-106:从后序和中序构造二叉树
leetcode-889:根据前序和后序遍历构造二叉树

环环无敌大可爱💃

posted @ 2022-04-19 10:19  盐小果  阅读(308)  评论(0编辑  收藏  举报