代码随想录day20|最大二叉树. 合并二叉树. 二叉搜索树中的搜索. 验证二叉搜索树

最大二叉树

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

  1. 创建一个根节点,其值为 nums 中的最大值。
  2. 递归地在最大值 左边 的 子数组前缀上 构建左子树。
  3. 递归地在最大值 右边 的 子数组后缀上 构建右子树。

返回 nums 构建的 最大二叉树 。

分析  找到最值index后构造root. 左节点从[leftindex 到最值index], 右节点从[最值index+1,rightIndex]

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

    }

    private TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex){
        if(rightIndex-leftIndex<1){
            return null;
        }

        int maxIndex=leftIndex;
        int maxVal=nums[maxIndex];
        if(rightIndex-leftIndex==1){
            return new TreeNode(maxVal);
        }

        for (int i =leftIndex+1;i<rightIndex;i++){
            if(nums[i]>maxVal){
                maxVal=nums[i];
                maxIndex=i;
            }
        }

        TreeNode root=new TreeNode(maxVal);
        root.left=constructMaximumBinaryTree1(nums,leftIndex,maxIndex);
        root.right=constructMaximumBinaryTree1(nums,maxIndex+1,rightIndex);
        return root;
    }
}

合并二叉树

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

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

分析 按照递归三部曲来解决:

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

首先要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。

  1. 确定终止条件:

因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。

反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。

if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1
  1. 确定单层递归的逻辑:

单层递归的逻辑就比较好写了,这里我们重复利用一下t1这个树,t1就是合并之后树的根节点(就是修改了原来树的结构)。

那么单层递归中,就要把两棵树的元素加到一起。t1就是合并之后的根节点。

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        return mergeTree(root1,root2);
    }

    private TreeNode mergeTree(TreeNode root1,TreeNode root2){
        if(root1==null) return root2;
        if(root2==null) return root1;

        root1.val+=root2.val;
        root1.left=mergeTree(root1.left,root2.left);
        root1.right=mergeTree(root1.right,root2.right);
        return root1;
    }
}

二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点 root 和一个整数值 val

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

分析 

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

递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。

  1. 确定终止条件

如果root为空,或者找到这个数值了,就返回root节点。

  1. 确定单层递归的逻辑

看看二叉搜索树的单层递归逻辑有何不同。

因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。

如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。

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 (val < root.val) {
            return searchBST(root.left, val);
        } else {
            return searchBST(root.right, val);
        }
    }
}

验证二叉搜索树

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

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

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。
    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 && root.val <= max.val) {
                return false;
            }
            max = root;
            // 右
            boolean right = isValidBST(root.right);
            return right;
        }
    }
posted @ 2023-03-06 22:24  绝云气负青天  阅读(16)  评论(0)    收藏  举报