当前位置: 首页 > news >正文

代码随想录算法训练营第十五天

LeetCode题目:

  • 654. 最大二叉树
  • 617. 合并二叉树
  • 700. 二叉搜索树中的搜索
  • 98. 验证二叉搜索树
  • 2843. 统计对称整数的数目

其他:

今日总结
往期打卡


654. 最大二叉树

跳转: 654. 最大二叉树

学习: 代码随想录公开讲解

问题:

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

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

在这里插入图片描述

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

思路:

这道题要求构造二叉树,使用前序遍历先构造自身再构造子树比较符合直觉,当然,先构造子节点再构造父节点后序遍历也是没有问题的,不过需要先存储子节点再构造父节点,比较麻烦.当然,用中序遍历也是,只需要先处理到左根,再创建节点,再绑定右子树即可.所以说前中后序只是创建节点的位置不同.
但这题用层序遍历就不是很合适,因为数组不是很好划分,要存储全部路径的边界状态.
因为需要获取两个子节点再操作本节点,所以使用迭代法比较麻烦.

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

代码(前序递归实现):

class Solution {
    TreeNode getTree(int[] nums,int l,int r)
    {
        if(l>=r) return null;
        if(r-l==1) return new TreeNode(nums[l]);
        int index = l;
        int max = 0;
        for(int i=l;i<r;i++){
            if(nums[i]>max){
                max = nums[i];
                index = i;
            }
        }
        TreeNode root = new TreeNode(max);
        root.left = getTree(nums,l,index);
        root.right = getTree(nums,index+1,r);
        return root;
    }
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return getTree(nums,0,nums.length);
    }
}

617. 合并二叉树

跳转: 617. 合并二叉树

学习: 代码随想录公开讲解

问题:

给你两棵二叉树: root1root2

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

返回合并后的二叉树。

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

在这里插入图片描述

思路:

两棵树一起遍历,如果都不为null就合并,一方为null就返回另一方.
这里直接前序遍历

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( l o g n ) O(logn) O(logn)

代码:

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1==null) return root2;
        if(root2==null) return root1;
        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. 二叉搜索树中的搜索

跳转: 700. 二叉搜索树中的搜索

学习: 代码随想录公开讲解

问题:

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

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

思路:

这里直接利用二叉搜索树的性质选择递归方向即可

有效 二叉搜索树定义如下:

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

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( l o g n ) O(logn) O(logn)

代码:

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

98. 验证二叉搜索树

跳转: 98. 验证二叉搜索树

学习: 代码随想录公开讲解

问题:

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

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

思路:

右子树中所有节点都大于当前节点,左子树中所有节点都小于当前节点,基于此,可以使用边界收缩法,判断子节点是否在边界内

当然,二叉搜索树有一个很重要的性质,那就是中序遍历下单调递增.所以如果能想到这条性质可以降低编码复杂度,并提升代码效率.

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

代码(中序遍历):

class Solution {
    long pre = Long.MIN_VALUE;
    public boolean isValidBST(TreeNode root) {
        if(root==null) return true;
        if(!isValidBST(root.left)) return false;
        if(root.val<=pre) return false;
        pre = root.val;
        return isValidBST(root.right);
    }
}

代码(边界收缩):

class Solution {
    boolean handle(TreeNode root,long lBorder,long rBorder){
        if (root == null)
            return true;
        boolean a, b;
        a = true;
        b = true;
        if (root.left != null)
            if (root.left.val>lBorder&&root.left.val<root.val)
                a = handle(root.left,lBorder,root.val);
            else
                return false;
        if (root.right != null)
            if (root.right.val>root.val&&root.right.val<rBorder)
                b = handle(root.right,root.val,rBorder);
            else
                return false;

        return a&b;
    }
    public boolean isValidBST(TreeNode root) {
        return handle(root,Long.MIN_VALUE,Long.MAX_VALUE);
    }
}

2843. 统计对称整数的数目

跳转: 2843. 统计对称整数的数目

问题

给你两个正整数 lowhigh

对于一个由 2 * n 位数字组成的整数 x ,如果其前 n 位数字之和与后 n 位数字之和相等,则认为这个数字是一个对称整数。

返回在 [low, high] 范围内的 对称整数的数目

思路:

找特殊数,最简单的方法就是把所有可能用到的特殊数都记下来,然后枚举特殊数进行判断.当然范围较小的情况下遍历范围里的数其实也差不多
当然,也可以直接枚举每位判断

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

代码(哈希字典1):

class Solution {
    public int countSymmetricIntegers(int low, int high) {
        int[] hash = new int[1000];
        int l = 0;
        for(int i=1;i<10;i++){
            hash[l++] = i+10*i; 
        }
        for(int i=1;i<10;i++){
            for(int j=0;j<10;j++){
                for(int k=0;k<10&&k<=i+j;k++){
                    if(i+j-k>=10) continue;
                    hash[l++]=(i*1000+j*100+k*10+(i+j-k));
                }
            }
        }
        int ans = 0;
        for(int i:hash){
            if(i<low) continue;
            if(i>high||i==0) break;
            ans++;
        }
        return ans;
    }
}

代码(哈希字典2):

class Solution {
    public int countSymmetricIntegers(int low, int high) {
        int[] hash = new int[10001];
        for(int i=1;i<10;i++){
            hash[i+10*i]++; 
        }
        for(int i=1;i<10;i++){
            for(int j=0;j<10;j++){
                for(int k=0;k<10&&k<=i+j;k++){
                    if(i+j-k>=10) continue;
                    hash[(i*1000+j*100+k*10+(i+j-k))]++;
                }
            }
        }
        int ans = 0;
        for(int i = low;i<=high;i++){
            if(hash[i]==1) ans++;
        }
        return ans;
    }
}

总结

今天主要是复习了二叉搜索树相关的概念.

往期打卡

代码随想录算法训练营第十四天

代码随想录算法训练营第十三天

代码随想录算法训练营第十二天

代码随想录算法训练营第十一天

代码随想录算法训练营周末二

代码随想录算法训练营第十天

代码随想录算法训练营第九天

代码随想录算法训练营第八天

代码随想录算法训练营第七天

代码随想录算法训练营第六天

代码随想录算法训练营第五天

代码随想录算法训练营周末一

代码随想录算法训练营第四天

代码随想录算法训练营第三天

代码随想录算法训练营第二天

代码随想录算法训练营第一天

相关文章:

  • Shell四种配置文件的区别(~/.bashrc ~/.bash_profile ~/.zshrc ~/.profile)
  • JavaWeb-01-前端Web开发(HTML+CSS)
  • 甜心速达智慧潮流精选超市、即时零售新业态,打造可持续发展商业模式
  • Vulhub-DC-4靶场通关攻略
  • 操作系统 3.5-内存换入-请求调页
  • 【GIT】git pull --rebase 功能解析
  • 《Vue Router实战教程》20.路由懒加载
  • 【Linux 进程控制】—— 进程亦生生不息:起于鸿蒙,守若空谷,归于太虚
  • 【OpenCV 对图片做旋转操作】仿射=旋转+平移+缩放+剪切
  • 数据仓库标准库模型架构相关概念浅讲
  • VMWare Workstation Pro17.6最新版虚拟机详细安装教程(附安装包教程)
  • 使用animation来实现时段的滚动效果
  • 数据库主从延迟全解析:原因、影响与解决之道
  • [Java基础]StringBuilder解析
  • swift菜鸟教程11-12(数组与字典)
  • 使用django实现windows任务调度管理
  • 怎么样在Windows系统上安装 的 WPS JS 插件
  • AUTO-DL 910B + mindspeed-llm 4层DeepSeek V3微调
  • MQTT的构成、使用场景、工作原理介绍
  • EAL4+ vs EAL7:高安全场景下的等级选择策略
  • 大连网站建设讯息/杭州seo网络推广
  • 做地产网站/seo关键词排名在线查询
  • 查看一个网站的备案/seo推广知识
  • 免费自助建网站软件/百度推广登录平台官网
  • javacms开源免费/长沙正规竞价优化推荐
  • 全球做的比较好的网站有哪些/网站seo快速排名