代码随想录算法训练营第二十天 | ● 654.最大二叉树 ● 617.合并二叉树 ● 700.二叉搜索树中的搜索 ● 98.验证二叉搜索树

今日内容

654.最大二叉树

617.合并二叉树

700.二叉搜索树中的搜索

98.验证二叉搜索树

详细布置

654.最大二叉树

又是构造二叉树,昨天大家刚刚做完 中序后序确定二叉树,今天做这个 应该会容易一些, 先看视频,好好体会一下 为什么构造二叉树都是 前序遍历

题目链接/文章讲解:https://programmercarl.com/0654.%E6%9C%80%E5%A4%A7%E4%BA%8C%E5%8F%89%E6%A0%91.html

视频讲解:https://www.bilibili.com/video/BV1MG411G7ox

 

构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。

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

参数就是传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。

  • 确定终止条件

题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。

那么应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。 这表示一个数组大小是1的时候,构造了一个新的节点,并返回。

  • 确定单层递归的逻辑

这里有三步工作

  1. 先要找到数组中最大的值和对应的下标, 最大的值构造根节点,下标用来下一步分割数组。
  2. 最大值所在的下标左区间 构造左子树:要判断maxValueIndex > 0,因为要保证左区间至少有一个数值。
  3. 最大值所在的下标右区间 构造右子树:判断maxValueIndex < (nums.size() - 1),确保右区间至少有一个数值。
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return constructMaximumBinaryTree1(nums,0, nums.length);
    }
    public TreeNode constructMaximumBinaryTree1(int[] nums,int leftIndex,int rightIndex){
        //终止条件,区间里没有元素
        if (rightIndex - leftIndex < 1){
            return null;
        }
        //叶子结点
        if (rightIndex - leftIndex == 1){
            return new TreeNode(nums[leftIndex]);
        }
        int maxIndex = leftIndex;
        int maxVal = nums[maxIndex];
        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;
    }
}

617.合并二叉树

这次是一起操作两个二叉树了, 估计大家也没一起操作过两个二叉树,也不知道该如何一起操作,可以看视频先理解一下。 优先掌握递归。

题目链接/文章讲解:https://programmercarl.com/0617.%E5%90%88%E5%B9%B6%E4%BA%8C%E5%8F%89%E6%A0%91.html

视频讲解:https://www.bilibili.com/video/BV1m14y1Y7JK

重复利用一下t1这个树,t1就是合并之后树的根节点(就是修改了原来树的结构)

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1 == null) {
            return root2;
        }
        if (root2 == null) {
            return root1;
        }
        root1.val += root2.val;
        root1.left = mergeTrees(root1.left,root2.left);
        root1.right = mergeTrees(root1.right,root2.right);
        return root1;
    }
}

700.二叉搜索树中的搜索

递归和迭代 都可以掌握以下,因为本题比较简单, 了解一下 二叉搜索树的特性

题目链接/文章讲解: https://programmercarl.com/0700.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E6%90%9C%E7%B4%A2.html

视频讲解:https://www.bilibili.com/video/BV1wG411g7sF

二叉搜索树是一个有序树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树
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);
    }
}
info
			解答成功:
			执行耗时:0 ms,击败了100.00% 的Java用户
			内存消耗:42.1 MB,击败了18.26% 的Java用户
			if (val < root.val) {
                return searchBST(root.left, val);
            } else {
                return searchBST(root.right, val);
            }
info
			解答成功:
			执行耗时:0 ms,击败了100.00% 的Java用户
			内存消耗:41.6 MB,击败了82.91% 的Java用户
class Solution {
    // 迭代,利用二叉搜索树特点,优化,可以不需要栈
    public TreeNode searchBST(TreeNode root, int val) {
        while (root != null)
            if (val < root.val) root = root.left;
            else if (val > root.val) root = root.right;
            else return root;
        return null;
    }
}
info
			解答成功:
			执行耗时:0 ms,击败了100.00% 的Java用户
			内存消耗:41.8 MB,击败了55.90% 的Java用户

98.验证二叉搜索树

遇到 搜索树,一定想着中序遍历,这样才能利用上特性。

但本题是有陷阱的,可以自己先做一做,然后在看题解,看看自己是不是掉陷阱里了。这样理解的更深刻。

题目链接/文章讲解:https://programmercarl.com/0098.%E9%AA%8C%E8%AF%81%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html

视频讲解:https://www.bilibili.com/video/BV18P411n7Q4

  • 确定递归函数,返回值以及参数

要定义一个max的全局变量,用来比较遍历的节点是否有序

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-01-12 23:53  染醉霜林  阅读(26)  评论(0)    收藏  举报