CSDN每日一题学习训练——Java版(二叉搜索树迭代器、二叉树中的最大路径和、按要求补齐数组)

版本说明

当前版本号[20231115]。

版本修改说明
20231115初版

目录

文章目录

  • 版本说明
  • 目录
  • 二叉搜索树迭代器
    • 题目
    • 解题思路
    • 代码思路
    • 参考代码
  • 二叉树中的最大路径和
    • 题目
    • 解题思路
    • 代码思路
    • 参考代码
  • 按要求补齐数组
    • 题目
    • 解题思路
    • 代码思路
    • 参考代码

二叉搜索树迭代器

题目

实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器:

BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。
boolean hasNext() 如果向指针右侧遍历存在数字,则返回 true ;否则返回 false 。
int next()将指针向右移动,然后返回指针处的数字。

注意,指针初始化为一个不存在于 BST 中的数字,所以对 next() 的首次调用将返回 BST 中的最小元素。

你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 的中序遍历中至少存在一个下一个数字。

示例:

image-20231115220727677

输入
[“BSTIterator”, “next”, “next”, “hasNext”, “next”, “hasNext”, “next”, “hasNext”, “next”, “hasNext”]
[[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]
输出
[null, 3, 7, true, 9, true, 15, true, 20, false]

解释
BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]);
bSTIterator.next(); // 返回 3
bSTIterator.next(); // 返回 7
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 9
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 15
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 20
bSTIterator.hasNext(); // 返回 False

提示:

树中节点的数目在范围 [1, 105] 内
0 <= Node.val <= 106
最多调用 105 次 hasNext 和 next 操作

进阶:

你可以设计一个满足下述条件的解决方案吗?next() 和 hasNext() 操作均摊时间复杂度为 O(1) ,并使用 O(h) 内存。其中 h 是树的高度。

解题思路

  1. 初始化一个空栈,用于存储中序遍历过程中的节点。
  2. 从根节点开始,将所有左子节点依次入栈,直到遇到没有左子节点的节点。
  3. 当栈不为空时,弹出栈顶元素,将其值返回,并将其右子节点依次入栈,直到遇到没有右子节点的节点。
  4. 重复步骤2和3,直到栈为空。

代码思路

  1. 这段代码实现了一个二叉搜索树的迭代器。

  2. 首先定义了一个TreeNode类,表示二叉树的节点,包含一个整数值val和左右子节点left、right。

    // 定义一个二叉树节点类
    public class TreeNode {
        int val; // 节点值
        TreeNode left; // 左子节点
        TreeNode right; // 右子节点
        // 构造函数,初始化节点值
        TreeNode(int x) {
            val = x;
        }
    }
    
  3. 然后定义了一个BSTIterator类,用于实现二叉搜索树的迭代器。这个迭代器使用了一个LinkedList来存储遍历过程中的节点。

    // 定义一个二叉搜索树迭代器类
    class BSTIterator {
        LinkedList<TreeNode> stack = new LinkedList<>(); // 使用链表存储遍历过程中的节点
    
  4. 在构造函数中,将根节点root及其左子树的所有节点依次入栈。这样,栈顶元素就是当前最小的节点。

      // 构造函数,接收根节点作为参数,将根节点及其左子树的所有节点依次入栈
        public BSTIterator(TreeNode root) {
            TreeNode cur = root;
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
        }
    
  5. next()方法用于获取下一个节点的值。首先弹出栈顶元素,然后将该节点的右子树及其左子树的所有节点依次入栈。这样,下一次调用next()方法时,栈顶元素就是当前最小的节点。

     // next() 方法,返回下一个节点的值
        public int next() {
            TreeNode n = stack.pop(); // 弹出栈顶元素
            TreeNode cur = n.right; // 获取弹出节点的右子节点
            while (cur != null) {
                stack.push(cur); // 将右子节点及其左子树的所有节点依次入栈
                cur = cur.left;
            }
            return n.val; // 返回弹出节点的值
        }
    
  6. hasNext()方法用于判断是否还有下一个节点。只要栈不为空,就说明还有下一个节点。

     // hasNext() 方法,判断是否还有下一个节点
        public boolean hasNext() {
            return !stack.isEmpty(); // 如果栈不为空,则说明还有下一个节点
        }
    

参考代码

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) {
        val = x;
    }
}
class BSTIterator {
    LinkedList<TreeNode> stack = new LinkedList<>();
    public BSTIterator(TreeNode root) {
        TreeNode cur = root;
        while (cur != null) {
            stack.push(cur);
            cur = cur.left;
        }
    }
    public int next() {
        TreeNode n = stack.pop();
        TreeNode cur = n.right;
        while (cur != null) {
            stack.push(cur);
            cur = cur.left;
        }
        return n.val;
    }
    public boolean hasNext() {
        return !stack.isEmpty();
    }
}
/**
 * Your BSTIterator object will be instantiated and called as such:
 * BSTIterator obj = new BSTIterator(root);
 * int param_1 = obj.next();
 * boolean param_2 = obj.hasNext();
 */

二叉树中的最大路径和

题目

路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ,返回其 最大路径和 。

示例 1:

image-20231115224820246

输入:root = [1,2,3]
输出:6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

示例 2:

image-20231115224846284

输入:root = [-10,9,20,null,null,15,7]
输出:42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42

提示:

树中节点数目范围是 [1, 3 * 104]
-1000 <= Node.val <= 1000

解题思路

  1. 初始化一个全局变量 maxSum,用于存储最大路径和,初始值为 Integer.MIN_VALUE。
  2. 定义一个递归函数 maxGain,输入参数为 TreeNode 类型的节点 node。
  3. 如果节点为空,返回 0。
  4. 计算左子树的最大增益 leftGain,如果小于等于 0,则取 0。
  5. 计算右子树的最大增益 rightGain,如果小于等于 0,则取 0。
  6. 计算新路径的价格 priceNewpath,即当前节点的值加上左右子树的最大增益。
  7. 更新 maxSum,将其设置为 maxSum 和 priceNewpath 中的较大值。
  8. 返回当前节点的值加上左右子树中增益较大的那个值。
  9. 在 maxPathSum 函数中调用 maxGain 函数,并返回 maxSum。

代码思路

  1. 首先定义了一个名为Solution的类,其中包含一个名为maxSum的整数变量,用于存储最大路径和。

    // 定义一个名为Solution的类
    class Solution {
        // 初始化最大路径和为整数最小值
        int maxSum = Integer.MIN_VALUE;
        // 定义一个名为maxPathSum的方法,接收一个TreeNode类型的参数root,返回一个整数值
    
  2. maxPathSum(TreeNode root):这是主方法,它接受一个二叉树的根节点作为参数,并返回最大路径和。在这个方法中,首先调用maxGain方法来计算最大路径和,然后返回maxSum变量的值。

     public int maxPathSum(TreeNode root) {
            // 调用maxGain方法计算最大路径和
            maxGain(root);
            // 返回最大路径和
            return maxSum;
        }
    
  3. maxGain(TreeNode node):这是一个辅助方法,用于递归地计算以给定节点为起点的最大路径和。它首先检查节点是否为空,如果为空则返回0。

        // 定义一个名为maxGain的方法,接收一个TreeNode类型的参数node,返回一个整数值
        public int maxGain(TreeNode node) {
            // 如果节点为空,返回0
            if (node == null) {
                return 0;
            }
    
  4. 然后,它分别计算左子树和右子树的最大增益(即不选择该子树的情况下的最大路径和),并将它们与当前节点的值相加得到新路径的价格。

       // 计算左子树的最大增益,如果小于0则取0
            int leftGain = Math.max(maxGain(node.left), 0);
            // 计算右子树的最大增益,如果小于0则取0
            int rightGain = Math.max(maxGain(node.right), 0);
            // 计算新路径的价格
            int priceNewpath = node.val + leftGain + rightGain;
    
  5. 接着,它将新路径的价格与当前的最大路径和进行比较,更新maxSum变量的值。最后,它返回当前节点的值加上左右子树中增益较大的那个值,作为以当前节点为起点的最大路径和。

       // 更新最大路径和
            maxSum = Math.max(maxSum, priceNewpath);
    
  6. 通过递归地遍历整个二叉树,该方法可以找到从根节点到任意叶子节点的最大路径和,并将其存储在maxSum变量中。最终,maxPathSum方法将返回这个最大路径和。

     // 返回当前节点的值加上左右子树中增益较大的那个值
            return node.val + Math.max(leftGain, rightGain);
    

参考代码

这段代码是二叉树路径和的最大值问题。

class Solution {
    int maxSum = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        maxGain(root);
        return maxSum;
    }
    public int maxGain(TreeNode node) {
        if (node == null) {
            return 0;
        }
        int leftGain = Math.max(maxGain(node.left), 0);
        int rightGain = Math.max(maxGain(node.right), 0);
        int priceNewpath = node.val + leftGain + rightGain;
        maxSum = Math.max(maxSum, priceNewpath);
        return node.val + Math.max(leftGain, rightGain);
    }
}

按要求补齐数组

题目

给定一个已排序的正整数数组 nums,和一个正整数 n 。从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。

示例 1:

输入: nums =
[1,3]
, n =
6

输出: 1
解释:
根据 nums 里现有的组合
[1], [3], [1,3]
,可以得出
1, 3, 4

现在如果我们将
2
添加到 nums 中, 组合变为:
[1], [2], [3], [1,3], [2,3], [1,2,3]

其和可以表示数字
1, 2, 3, 4, 5, 6
,能够覆盖
[1, 6]
区间里所有的数。
所以我们最少需要添加一个数字。

image-20231115230203186

示例 2:

输入: nums =
[1,5,10]
, n =
20

输出: 2
解释: 我们需要添加
[2, 4]

示例 3:

输入: nums =
[1,2,2]
, n =
5

输出: 0

image-20231115230223208

解题思路

  1. 初始化 patches 为 0,表示需要补充的数字个数;i 为 0,表示当前处理的 nums 数组中的索引;miss 为 1,表示当前未覆盖的数字范围的最小值。
  2. 当 miss <= n 时,执行循环: a. 如果 i < nums.length 且 nums[i] <= miss,说明可以用 nums[i] 来表示 miss,将 miss 加上 nums[i],并将 i 向右移动一位。 b. 否则,说明需要补充一个数字,使得 miss 可以表示为两个数的和,即 miss = miss + miss。将 miss 加上 miss,并将 patches 加 1。
  3. 返回 patches。

代码思路

  1. 初始化变量patches为0,表示已经使用的补丁数量;变量i为0,表示当前处理的nums数组中的索引;变量miss为1,表示当前未覆盖的数字范围的最小值。

       // 初始化变量patches为0,i为0,miss为1
            int patches = 0, i = 0;
            long miss = 1;
    
  2. miss小于等于n时,执行循环。这是因为我们需要确保覆盖从1到n的所有数字。

  3. 在循环中,首先检查i是否小于nums的长度且nums[i]小于等于miss。如果是,则说明我们可以使用nums[i]来扩展当前的覆盖范围,因此将miss加上nums[i]并将i加1。

     // 当miss小于等于n时,执行循环
            while (miss <= n) {
                // 如果i小于nums的长度且nums[i]小于等于miss,则将miss加上nums[i]并将i加1
                if (i < nums.length && nums[i] <= miss)
                    miss += nums[i++];
    
  4. 如果上述条件不满足,说明我们需要增加一个新的补丁来扩展当前的覆盖范围。此时,将miss加上miss(即当前未覆盖的数字范围的最小值),并将patches加1。

     // 否则,将miss加上miss,并将patches加1
                else {
                    miss += miss;
                    patches++;
                }
    
  5. 循环结束后,返回patches的值,即所需的最少补丁数量。

        // 返回patches的值
        return patches;

参考代码

这段代码是计算将1到n之间的所有数字都覆盖所需要的最少的补丁数量。

class Solution {
    public int minPatches(int[] nums, int n) {
        int patches = 0, i = 0;
        long miss = 1;
        while (miss <= n) {
            if (i < nums.length && nums[i] <= miss)
                miss += nums[i++];
            else {
                miss += miss;
                patches++;
            }
        }
        return patches;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/150570.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UE4动作游戏实例RPG Action解析三:实现效果,三连击Combo,射线检测,显示血条,火球术

一、三连Combo 实现武器三连击,要求: 1.下一段Combo可以随机选择, 2.在一定的时机才能再次检测输入 3. 等当前片段播放完才播放下一片段 1.1、蒙太奇设置 通过右键-新建蒙太奇片段,在蒙太奇里创建三个片段,并且移除相关连接,这样默认只会播放第一个片段 不同片段播…

requests 2.13.0 版本的 https 连接慢漏提示

# 解决方案 requests 2.13.0 版本的 https 连接慢漏问题 问题背景&#xff1a;在使用requests 2.13.0版本时&#xff0c;发现存在一个缓慢的泄漏问题。这个问题只在使用https连接时出现。经过调查&#xff0c;发现这个问题与pyOpenSSL的使用有关。在使用pyOpenSSL与requests 2.…

Ps:利用 AI 技术创建人像皮肤图层蒙版

Photoshop 并没有提供专门选择人像皮肤的工具或命令&#xff08;色彩范围中的肤色选择非常不精准&#xff09;&#xff0c;但较新版的 Camera Raw 滤镜则提供了基于 AI 技术的选择人物并创建面部和身体皮肤蒙版的功能。 如果能将 Camera Raw 滤镜中创建的 AI 皮肤蒙版转换成 Ps…

Qt图形视图框架:QGraphicsItem详解

Qt图形视图框架&#xff1a;QGraphicsItem详解 Chapter1 Qt图形视图框架&#xff1a;QGraphicsItem详解Chapter2 自定义QGraphicsItem实现平移、改变尺寸和旋转1. 平移2. 改变尺寸3. 旋转完整代码如下&#xff1a;头文件源文件 Chapter1 Qt图形视图框架&#xff1a;QGraphicsIt…

初试 jmeter做压力测试

一.前言 压力测试是每一个Web应用程序上线之前都需要做的一个测试&#xff0c;他可以帮助我们发现系统中的瓶颈问题&#xff0c;减少发布到生产环境后出问题的几率&#xff1b;预估系统的承载能力&#xff0c;使我们能根据其做出一些应对措施。所以压力测试是一个非常重要的步…

nodejs+vue黄河风景线旅游网站的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计

本文首先对该系统进行了详细地描述&#xff0c;然后对该系统进行了详细的描述。管理人员增加了系统首页、个人中心、用户管理、景点分类管理、景点简介管理、旅游路线管理、文章分类管理、公告文章管理、系统管理理等功能。这套黄河风景线旅游网站是根据当前的现实需要&#xf…

接口

文章目录 概述语法使用特性接口的继承抽象类和接口的区别 概述 电脑的USB口上&#xff0c;可以插&#xff1a;U盘、鼠标、键盘…所有符合USB协议的设备 电源插座插孔上&#xff0c;可以插&#xff1a;电脑、电视机、电饭煲…所有符合规范的设备 通过上述例子可以看出&#xff…

.NET 7 创建Android项目 (拥有原生的界面设计能力,比MAUI更好的性能)

vs2022默认移动开发使用的是maui项目模板&#xff0c;maui确实有很多亮点&#xff0c;就是对比android原生项目性能还需要优化&#xff0c;特别是启动app时无法达到秒开。后来发现vs2022中依然可以直接创建android项目&#xff0c;性能和原生Android基本一致。 1、搜索模板 dot…

OPPO Watch纯手机开启远程ADB调试

Wear OS手表中&#xff0c;我们可以直接在开发者设置中打开WiFi调试。但是这在OPPO等魔改Android系统中不再奏效。 需要什么&#xff1f;&#xff1f; 手表一台手机一个OTG转接头一个手表充电器一个 演示设备 手机&#xff1a; OPPO Find X手表&#xff1a; OPPO Watch 1代 …

Mysql MMM

MMM概述 MMM(Master-Master replication manager for MvSQL&#xff0c;MySQL主主复制管理器&#xff09; 是一套支持双主故障切换和双主日常管理的脚本程序。 MMM 使用 Perl 语言开发&#xff0c;主要用来监控和管理MySQL Master-Master&#xff08;双主&#xff09;复制&…

S-Clustr(影子集群) 重磅更新!黑入工业PLC设备!

公告 项目地址:https://github.com/MartinxMax/S-Clustr 更新预告内容进度SIEMENS S7-200 SMART远程控制进行中 开发人员Blog联系方式提交时间提交内容授权情况ASH_HHhttps://blog.csdn.net/m0_53711047/article/details/133691537?spm1001.2014.3001.5502匿名2023-10-16 2…

性能测试 —— Jmeter接口处理不低于200次/秒-场景

需求&#xff1a;期望某个接口系统的处理能力不低于200次/秒&#xff0c;如何设计&#xff1f; ①这个场景是看服务器对某个接口的TPS值是否能大于等于200&#xff0c;就可以了&#xff1b; ②系统处理能力&#xff1a;说的就是我们性能测试中的TPS&#xff1b; ③只要设计一…

借助Spire.Doc for Java控件,将 ODT 转换为 PDF。

在通过电子邮件发送或与其他人共享 ODT 文件之前&#xff0c;您可能需要将该文件转换为 PDF&#xff0c;以便任何人都可以跨多个操作系统访问该文件。在本文中&#xff0c;您将学习如何使用Spire.Doc for Java在 Java 中将 ODT 转换为 PDF。 Spire.Doc 是一款专门对 Word 文档…

基于单片机的公交车报站系统(论文+源码)

1系统设计 本次课题为基于单片机的公交车报站系统&#xff0c;在此主要是基于Proteus平台展开设计&#xff0c;因此结合Proteus平台的特性&#xff0c;将功能设计如下&#xff1a; &#xff08;1&#xff09;公交车具有上行和下行两种状态&#xff0c;可以通过按键进行手动播…

保姆级教程之SABO-VMD-CNN-SVM的分类诊断,特征可视化

今天出一期基于SABO-VMD-CNN-SVM的分类诊断。 依旧是采用经典的西储大学轴承数据。基本流程如下&#xff1a; 首先是以最小包络熵为适应度函数&#xff0c;采用SABO优化VMD的两个参数。其次对每种状态的数据进行特征向量的求取&#xff0c;并为每组数据打上标签。然后将数据送入…

系列二、类装载器ClassLoader

一、能干嘛 1.1、方法区 存放类的描述信息的地方。 1.2、JVM中的类装载器 1.3、获取ClassLoader的方式 /*** Author : 一叶浮萍归大海* Date: 2023/11/16 0:08* Description: 获取类的加载器的方式*/ public class ClassLoaderMainApp {public static void main(String[] arg…

【linux】centos7 yum安装nginx

查看系统中是否已安装 nginx 服务 yum list | grep nginx查看nginx运行进程 ps -ef | grep nginx添加源 rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm 安装Nginx yum install -y nginx 查看nginx安装目录 find …

vagrant+virtualbox的踩坑记录

vagrant virtualbox 文章目录 vagrant virtualbox一、导入虚拟机ova文件失败二、修改虚拟机的保存位置三、无法使用xshell等软件用密码进行连接四、vagrant up失败 一、导入虚拟机ova文件失败 背景&#xff1a;手动删除了虚拟机文件导致无法重新导入相同名称虚拟机的ova文件…

一起学docker系列之二深入理解Docker:基本概念、工作原理与架构

目录 前言1 Docker的基本概念2 Docker的基本组成3 docker工作原理4 docker架构5 Docker详细工作过程结语 前言 在当今的软件开发和部署中&#xff0c;Docker已经成为一种不可或缺的工具。它简化了应用程序的打包、交付和运行&#xff0c;同时提供了强大的隔离性和可移植性。本…

微信小程序H5 uniapp

最近微信小程序对有视频播放的审核严&#xff0c;需要提供“文娱类资质”。而申请这个资质比较繁琐。所以我们在小程序上用web-view做跳转到H5&#xff0c;H5使用uniapp编写。这是小程序关于web-view文档说明。https://developers.weixin.qq.com/miniprogram/dev/component/web…