0
点赞
收藏
分享

微信扫一扫

代码随想录:● 654.最大二叉树 ● 617.合并二叉树 ● 700.二叉搜索树中的搜索 ● 98.验证二叉搜索树

 654.最大二叉树 

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

  • 二叉树的根是数组中的最大元素。
  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。
  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。

通过给定的数组构建最大二叉树,并且输出这个树的根节点。

示例 :

代码随想录:● 654.最大二叉树  ● 617.合并二叉树  ● 700.二叉搜索树中的搜索  ● 98.验证二叉搜索树 _二叉树

提示:

给定的数组的大小在 [1, 1000] 之间。

解析:

题目所示,先找出最大值为根,然后根据最大值左边构建左子树,最大值右边构建右子树,天然的前序遍历构建二叉树。

递归三部曲->(左闭右开区间)

1、确定递归函数的参数和返回值

2、确定终止条件:传入的数组大小为1,说明遍历到了叶子节点,这时候应该定义一个新的节点,并把数组的数值复制给新的节点。

3、确定单层递归逻辑:

           3.1-找到数组中最大的值和对应的下标,最大值构建根节点,下标用来下一步分隔数组。

           3.2-最大值所在下标的左区间构造左子树

           3.3-最大值所在下标的右区间构造右子树

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return function(nums,0,nums.length);
    }

    public TreeNode function(int[] nums, int left, int right){
        if(right - left < 1){
            return null;
        }
        if(right - left == 1){
            return new TreeNode(nums[left]); 
        }
        int maxIndex = left;
        int maxValue = nums[maxIndex];
        for(int i = left+1; i < right; i++){
            if(nums[i] > maxValue){
                maxValue = nums[i];
                maxIndex = i;
            }
        }
        TreeNode root = new TreeNode(maxValue);
        //左闭右开
        root.left = function(nums,left,maxIndex);
        //左闭右开
        root.right = function(nums,maxIndex+1,right);
        return root;
    }
}

617.合并二叉树

力扣题目链接(opens new window)

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:

代码随想录:● 654.最大二叉树  ● 617.合并二叉树  ● 700.二叉搜索树中的搜索  ● 98.验证二叉搜索树 _二叉搜索树_02

注意: 合并必须从两个树的根节点开始。

解析:

比较简单,分几种情况讨论,然后前序遍历相加即可。

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        //递归
        if(root1 == null && root2 == null){
            return null;
        }
        if(root1 != null && root2 == null){
            return root1;
        }
        if(root1 == null && root2 != null){
            return root2;
        }
        TreeNode root = new TreeNode(root1.val + root2.val);
        root.left = mergeTrees(root1.left, root2.left);
        root.right = mergeTrees(root1.right,root2.right);
        return root;
    }
}

700.二叉搜索树中的搜索

力扣题目地址(opens new window)

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

例如,

代码随想录:● 654.最大二叉树  ● 617.合并二叉树  ● 700.二叉搜索树中的搜索  ● 98.验证二叉搜索树 _二叉树_03

在上述示例中,如果要找的值是 5,但因为没有节点值为 5,我们应该返回 NULL

解析:

递归法比较简单,也是可以用前序遍历的方法,但要注意,不能直接的调用searchBST函数,因为这个函数是有返回值的,需要有个变量来承接该函数。

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null || root.val == val) return root;
        TreeNode left = searchBST(root.left,val);
        if(left != null) return left;
        return searchBST(root.right,val);
    }
}

注意到这是二叉搜索树,所以可以有优化方案:

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null || root.val == val) return root;
        if(root.val > val) return searchBST(root.left,val);
        else return searchBST(root.right,val);
    }
}

98.验证二叉搜索树

力扣题目链接(opens new window)

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

代码随想录:● 654.最大二叉树  ● 617.合并二叉树  ● 700.二叉搜索树中的搜索  ● 98.验证二叉搜索树 _二叉树_04

解析: 

1、递归法,因为是BST,所以要注意中序遍历的话一定是有序的,这题我是直接看的题解,所以没有踩那几个陷阱。但我拿到题目的第一反应,也是打算淡出的比较左节点小于中间节点,右节点大于中间节点就完事了。这是错误的,只有左子树的全部节点小于根节点,右子树的全部节点大于根节点才算有效BST。这时候就需要一个max作为中间节点,只要左子树中的max节点是小于根节点即可满足要求。

单层递归逻辑:中序遍历max,只要max >= root.val, 就返回false

class Solution {
    TreeNode max;
    public boolean isValidBST(TreeNode root) {
        if(root == null) return true;
        boolean left = isValidBST(root.left);
        if(!left) return false;
        if(max != null && max.val >= root.val)
            return false;
        max = root;
        boolean right = isValidBST(root.right);
        return right;
    }
}

2、利用二叉搜索树特性,中序遍历是有序的,可以把值都保存到一个数组中,然后判断这个数组是否有序

class Solution {
    List<Integer> list = new ArrayList<>();
    public boolean isValidBST(TreeNode root) {
        search(root);
        for(int i = 1; i < list.size(); i++){
            if(list.get(i) <= list.get(i-1)){
                return false;
            }
        }
        return true;
    }

    public void search(TreeNode root){
        if(root == null) return;
        //左
        search(root.left);
        //中
        list.add(root.val);
        //右
        search(root.right);
    }
}

3、迭代法:这个比较生疏,照着题解看一眼回顾回顾

class Solution {
    public boolean isValidBST(TreeNode root) {
        if(root == null){
            return true;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode pre = null;
        while(root != null || !stack.isEmpty()){
            while(root != null){
                stack.push(root);
                root = root.left;
            }
            TreeNode pop = stack.pop();
            if(pre != null && pop.val <= pre.val)
                return false;
            pre = pop;
            root = pop.right;
        }
        return true;
    }
}

举报

相关推荐

二叉树|654.最大二叉树

0 条评论