每日算法-250328
记录今天学习和解决的LeetCode算法题。
92. 反转链表 II
题目

思路
本题要求反转链表中从 left 到 right 位置的节点。我们可以采用 头插法 的思路来反转指定区间的链表。
具体来说,我们首先定位到 left 位置节点的前一个节点 prev。然后,从 left 位置开始,依次将 left + 1 到 right 位置的节点移动到 prev 节点的后面,也就是反转区间的“头部”。
解题过程
-
虚拟头节点 (Dummy Node): 为了方便处理
left = 1的情况(即反转从头节点开始),我们创建一个虚拟头节点dummy,并让dummy.next指向原始链表的头节点head。最终返回结果时返回dummy.next。 -
定位
prev节点: 我们需要找到反转区间的前一个节点,记为prev。通过一个循环,将prev指针从dummy开始向后移动left - 1步,使其指向第left - 1个节点。 -
定位
cur节点:cur指针初始化为prev.next,即反转区间的第一个节点(第left个节点)。 -
执行反转 (头插法): 进行
right - left次操作。在每次操作中:- 记录
cur的下一个节点,记为curNext。这curNext就是本次需要移动到反转区间头部的节点。 - 让
cur的next指针指向curNext的下一个节点,即将curNext从链表中暂时断开。 (cur.next = curNext.next;) - 将
curNext插入到prev节点的后面:让curNext的next指针指向当前反转区间的第一个节点 (prev.next)。 (curNext.next = prev.next;) - 更新
prev的next指针,使其指向新插入的curNext,这样curNext就成为了新的反转区间的第一个节点。 (prev.next = curNext;) - 注意:在这个过程中,
cur指针始终指向原来的第left个节点,它在反转后会成为反转区间的最后一个节点。prev指针始终不变,指向反转区间的前一个节点。
- 记录
-
返回结果: 所有操作完成后,
dummy.next指向的就是新链表的头节点,返回dummy.next。
复杂度
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是链表的长度。需要遍历链表找到
prev节点,然后进行right - left次节点移动操作。 - 空间复杂度: O ( 1 ) O(1) O(1),只使用了常数级别的额外空间(几个指针变量)。
Code
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseBetween(ListNode head, int left, int right) {// 创建虚拟头节点,简化边界处理(如 left=1)ListNode dummy = new ListNode(0);dummy.next = head;// 1. 移动 prev 指针到第 left-1 个节点ListNode prev = dummy;for (int i = 1; i < left; i++) {prev = prev.next;}// 2. cur 指针指向第 left 个节点,即反转区间的起始节点ListNode cur = prev.next;// 3. 执行头插法反转 [left, right] 区间// 进行 right - left 次操作for (int i = left; i < right; i++) {// a. 记录待移动的节点 curNextListNode curNext = cur.next;// b. cur 指向 curNext 的下一个节点,将 curNext 从链表中断开cur.next = curNext.next;// c. 将 curNext 插入到 prev 之后(成为反转区间的新头部)curNext.next = prev.next;// d. 更新 prev 的 next 指针prev.next = curNext;}// 4. 返回新链表的头节点return dummy.next;}
}
1004. 最大连续1的个数 III
题目

思路
本题可以使用 滑动窗口 的方法解决。
核心思想是维护一个窗口 [left, right],使得这个窗口内包含的 0 的数量不超过 k。在窗口滑动过程中,不断更新窗口的最大长度。
解题过程
- 初始化: 设置窗口左右边界
left = 0,right = 0,当前窗口内0的计数count = 0,以及最大窗口长度maxLen = 0。 - 扩展窗口: 移动
right指针向右扩展窗口。- 如果
nums[right]是0,则count加 1。
- 如果
- 收缩窗口: 当窗口内
0的数量count超过k时,需要收缩窗口。- 移动
left指针向右收缩窗口。 - 如果移出窗口的元素
nums[left]是0,则count减 1。 - 持续收缩直到
count <= k。
- 移动
- 更新结果: 在每次窗口调整(扩展或收缩)后,当前窗口
[left, right]都是一个合法的窗口(0的数量不超过k)。计算当前窗口长度right - left + 1,并更新maxLen = Math.max(maxLen, right - left + 1)。 - 遍历结束: 当
right指针到达数组末尾时,maxLen即为所求的最大连续1的个数(允许翻转k个0)。 - 返回结果: 返回
maxLen。
复杂度
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组
nums的长度。每个元素最多被left和right指针访问一次。 - 空间复杂度: O ( 1 ) O(1) O(1),只使用了常数级别的额外空间。
Code
class Solution {public int longestOnes(int[] nums, int k) {int maxLen = 0; // 记录最大窗口长度int zeroCount = 0; // 记录当前窗口内 0 的个数int left = 0; // 窗口左边界// right 指针负责扩展窗口for (int right = 0; right < nums.length; right++) {// 如果新进入窗口的元素是 0,增加 zeroCountif (nums[right] == 0) {zeroCount++;}// 当窗口内 0 的数量超过 k 时,收缩窗口while (zeroCount > k) {// 如果移出窗口的元素是 0,减少 zeroCountif (nums[left] == 0) {zeroCount--;}// 移动左边界left++;}// 此时窗口 [left, right] 是合法的,更新最大长度maxLen = Math.max(maxLen, right - left + 1);}return maxLen;}
}
1658. 将 x 减到 0 的最小操作数
题目

思路
逆向思维 + 滑动窗口
题目要求从数组两端移除元素,使得移除元素的和等于 x,并求最小的操作次数(即移除元素的最少数量)。
我们可以反向思考:从两端移除元素,等价于在数组中间保留一段 连续 的子数组,使得这段子数组的和等于 totalSum - x。
那么问题就转化为:找到数组 nums 中和为 target = totalSum - x 的 最长 连续子数组的长度 maxLen。如果找到了这样的子数组,则最小操作数就是 n - maxLen(其中 n 是数组总长度)。如果找不到,则说明无法通过移除操作使和为 x,返回 -1。
我们可以使用滑动窗口来寻找和为 target 的最长连续子数组。
解题过程
- 计算总和: 计算数组
nums的总和totalSum。 - 计算目标和: 计算目标子数组的和
target = totalSum - x。 - 处理边界情况:
- 如果
target < 0,说明x比totalSum还大,不可能通过移除元素得到x,直接返回-1。 - 如果
target == 0,说明需要移除所有元素,其和才等于x(x == totalSum)。此时最长子数组长度为0,操作数为n - 0 = n。
- 如果
- 滑动窗口: 使用滑动窗口寻找和为
target的最长连续子数组。- 初始化
left = 0,currentSum = 0,maxLen = -1(-1表示尚未找到满足条件的子数组)。 - 用
right指针遍历数组,扩展窗口,将nums[right]加入currentSum。 - 当
currentSum > target时,收缩窗口:从currentSum中减去nums[left],并向右移动left指针,直到currentSum <= target。 - 如果
currentSum == target,说明找到了一个和为target的子数组[left, right]。更新maxLen = Math.max(maxLen, right - left + 1)。
- 初始化
- 返回结果:
- 如果
maxLen仍然是-1,说明没有找到和为target的子数组,返回-1。 - 否则,返回
n - maxLen。
- 如果
复杂度
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组
nums的长度。计算总和需要 O ( n ) O(n) O(n),滑动窗口也需要 O ( n ) O(n) O(n)。 - 空间复杂度: O ( 1 ) O(1) O(1),只使用了常数级别的额外空间。
Code
class Solution {public int minOperations(int[] nums, int x) {int n = nums.length;long totalSum = 0; // 使用 long 防止整数溢出for (int num : nums) {totalSum += num;}// 计算目标子数组的和long target = totalSum - x;// 边界情况:x 比总和还大,无解if (target < 0) {return -1;}// 边界情况:x 等于总和,需要移除所有元素if (target == 0) {return n;}int maxLen = -1; // 记录和为 target 的最长子数组长度,初始化为 -1 表示未找到long currentSum = 0;int left = 0;// 滑动窗口寻找和为 target 的最长子数组for (int right = 0; right < n; right++) {currentSum += nums[right];// 当窗口和大于 target 时,收缩窗口while (currentSum > target && left <= right) {currentSum -= nums[left];left++;}// 如果窗口和等于 target,更新 maxLenif (currentSum == target) {maxLen = Math.max(maxLen, right - left + 1);}}// 如果 maxLen 仍为 -1,说明找不到和为 target 的子数组,返回 -1// 否则,返回 n - maxLenreturn maxLen == -1 ? -1 : n - maxLen;}
}
相关文章:
每日算法-250328
记录今天学习和解决的LeetCode算法题。 92. 反转链表 II 题目 思路 本题要求反转链表中从 left 到 right 位置的节点。我们可以采用 头插法 的思路来反转指定区间的链表。 具体来说,我们首先定位到 left 位置节点的前一个节点 prev。然后,从 left 位置…...
从 Word 到 HTML:使用 Aspose.Words 轻松实现 Word 文档的高保真转换
从 Word 到 HTML:使用 Aspose.Words 轻松实现 Word 文档的高保真转换 前言一、环境准备二、核心代码实现1. 将 Word 转换为 HTML 文件流2. 优化超链接样式 三、测试效果四、总结 前言 在日常开发中,我们经常需要将 Word 文档转换为 HTML,用于…...
Android 设备实现 adb connect 连接的步骤
1. 检查设备的开发者选项 确保平板设备已开启开发者模式,并启用了USB调试。 2. 检查设备和电脑的网络连接 确保平板和电脑连接到同一个Wi-Fi网络,确认设备的 IP 地址是否正确。 通过 ping 命令测试: ping 192.168.3.243. 通过USB线进行初…...
【人工智能】解锁大模型潜力:Ollama 与 DeepSeek 的分布式推理与集群部署实践
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着大语言模型(LLM)的快速发展,其推理能力在自然语言处理、代码生成等领域展现出巨大潜力。然而,单机部署难以满足高并发、低延迟的需…...
离散的数据及参数适合用什么算法做模型
离散数据和参数适用的机器学习算法取决于具体任务(分类、回归、聚类等)、数据特点(稀疏性、类别数量等)以及业务需求。以下是针对离散数据的常用算法分类和选择建议: 1. 分类任务(离散目标变量) 经典算法 决策树(ID3/C4.5/CART) 直接处理离散特征,无需编码,可解释性…...
VMware 安装 Ubuntu 实战分享
VMware 安装 Ubuntu 实战分享 VMware 是一款强大的虚拟机软件,广泛用于多操作系统环境的搭建。本文将详细介绍如何在 VMware 中安装 Ubuntu,并分享安装过程中的常见问题及解决方法。 1. 安装前的准备工作 (1) 系统要求 主机操作系统:Windo…...
RSA 简介及 C# 和 js 实现【加密知多少系列_4】
〇、简介 谈及 RSA 加密算法,我们就需要先了解下这两个专业名词,对称加密和非对称加密。 对称加密:在同一密钥的加持下,发送方将未加密的原文,通过算法加密成密文;相对的接收方通过算法将密文解密出来原文…...
在IDEA中快速注释所有console.log
在IDEA中快速注释所有console.log 在前端IDEA中,快速注释所有console.log语句可以通过以下步骤实现2: 打开要修改的文件。使用快捷键CtrlF打开搜索框。点击打开使用正则搜索的开关或者通过AltR快捷键来打开。在搜索框输入[]*console.log[]*,…...
GPT-4o图像生成功能:技术突破与隐忧并存
2025年3月25日,OpenAI正式推出GPT-4o原生图像生成功能,宣称其实现了“文本到图像的终极跨越”。然而,这一被市场追捧的技术在短短72小时内便因用户需求过载触发限流,暴露出算力瓶颈与商业化矛盾的尖锐性。这场技术狂欢的背后&…...
SQL语言分类及命令详解(二)
目录 一、DQL (Data Query Language) 数据查询语言 核心命令:SELECT 基本语法: 详细分析: 高级特性: 示例: 二、DDL (Data Definition Language) 数据定义语言 核心命令 CREATE ALTER DROP TRUNCATE 详细…...
机器学习——LightGBM
LightGBM(light gradient boosting machine,轻量梯度提升机)是对XGBoost进行改进的模型版本,其三者之间的演变关系为:GBDT-》XGBoost-》LightGBM,依次对性能进行优化,尽管XGBoost已经很高效了,但是仍然有缺…...
linux 常见命令使用介绍
Linux 常见命令使用介绍 Linux 是一个功能强大的操作系统,其核心是命令行工具。掌握一些常用的 Linux 命令可以极大地提高工作效率。本文将详细介绍一些常见的 Linux 命令及其用法。 1. 文件与目录操作 ls - 列出文件和目录 # 查看当前目录下的所有文件和子目录&…...
故障识别 | 基于改进螂优化算法(MSADBO)优化变分模态提取(VME)结合稀疏最大谐波噪声比解卷积(SMHD)进行故障诊断识别,matlab代码
基于改进螂优化算法(MSADBO)优化变分模态提取(VME)结合稀疏最大谐波噪声比解卷积(SMHD)进行故障诊断识别 一、引言 1.1 机械故障诊断的背景和意义 在工业生产的宏大画卷中,机械设备的稳定运行…...
[已解决]服务器CPU突然飙高98%----Java程序OOM问题 (2024.9.5)
目录 问题描述问题排查问题解决参考资料 问题描述 业主单位服务器自8月29日晚上21:00起CPU突然飙高至98%,内存爆满,一直到9月5日: 问题排查 ①执行 top 命令查看Java进程PID top②执行top -Hp PID 命令查看具体的线程情况 top -Hp 3058输入上…...
spring如何用三级缓存解决循环依赖问题
spring为何会出现循环依赖问题? 我们举个会产生循环依赖的例子,如下所示,可以看到AService类中依赖了BService类,同理呢,BService类中依赖了AService类,这就是所谓的循环依赖。 Component("aService&…...
【C#】`Task.Factory.StartNew` 和 `Task.Run` 区别
Task.Factory.StartNew 和 Task.Run 都是用来启动新任务的,但它们有一些关键区别,我们来一条一条讲清楚(配例子 结论)。 🆚 1. 语法和使用目的 对比项Task.RunTask.Factory.StartNew用途简化写法,用于启动…...
谈谈空间复杂度考量,特别是递归调用栈空间消耗?
空间复杂度考量是算法设计的核心要素之一,递归调用栈的消耗问题在前端领域尤为突出。 以下结合真实开发场景进行深度解析: 一、递归调用栈的典型问题 1. 深层次DOM遍历的陷阱 // 危险操作:递归遍历未知层级的DOM树 function countDOMNode…...
【2.项目管理】2.4 Gannt图【甘特图】
甘特图(Gantt)深度解析与实践指南 📊 一、甘特图基础模板 项目进度表示例 工作编号工作名称持续时间(月)项目进度(周)1需求分析3▓▓▓░░░░░░░2设计建模3░▓▓▓░░░░░░3编码开发3.5░░░▓▓▓▓░░…...
Ai工作流工具有那些如Dify、coze扣子等以及他们是否开源
Dify (https://difycloud.com/) 核心定位:专业级 LLM 应用开发平台,支持复杂 AI 工作流构建与企业级管理。典型场景:企业智能客服、数据分析系统、复杂自动化流程构建等。适合需要深度定制、企业级管理和复杂 AI 逻辑…...
【项目】C++同步异步日志系统-包含运行教程
文章目录 项目介绍地址:https://gitee.com/royal-never-give-up/c-log-system 开发环境核心技术为什么需要日志系统同步日志异步日志 知识补充不定参宏函数__FILE____LINE____VA_ARGS__ C使用C使用左值右值sizeof...() 运算符完美转发完整例子sizeof...() 运算符获取…...
Yolo_v8的安装测试
前言 如何安装Python版本的Yolo,有一段时间不用了,Yolo的版本也在不断地发展,所以重新安装了运行了一下,记录了下来,供参考。 一、搭建环境 1.1、创建Pycharm工程 首先创建好一个空白的工程,如下图&…...
Success is the sum of small efforts repeated day in and day out.
(翻译:"成功是日复一日微小努力的总和。") 文章内容: Title: The Silent Power of Consistency (标题翻译:《持续坚持的无声力量》) Consistency is the quiet force that turns asp…...
软件兼容性测试的矩阵爆炸问题有哪些解决方案
解决软件兼容性测试中的矩阵爆炸问题主要有优先级划分、组合测试方法、自动化测试技术等方案。其中,组合测试方法尤其有效。组合测试通过科学的组合算法,能够显著降低测试用例的数量,同时保持较高的测试覆盖率,例如正交实验设计&a…...
嵌入式学习(32)-TTS语音模块SYN6288
一、概述 SYN6288 中文语音合成芯片是北京宇音天下科技有限公司于 2010年初推出的一款性/价比更高,效果更自然的一款中高端语音合成芯片。SYN6288 通过异步串口(UART)通讯方式,接收待合成的文本数据,实现文本到语音(或 TTS 语音)的转换。宇音天下于 2002…...
霸王茶姬小程序(2025年1月版)任务脚本
脚本用于自动执行微信小程序霸王茶姬的日常签到和积分管理任务。 脚本概述 脚本设置了定时任务(cron),每天运行两次,主要用于自动签到以获取积分,积分可以用来换取优惠券。 核心方法 constructor:构造函数,用于初始化网络请求的配置,设置了基础的 HTTP 请求头等。 logi…...
从零到一:打造顶尖生成式AI应用的全流程实战
简介 生成式AI正以前所未有的速度改变我们的世界,从内容创作到智能客服,再到医疗诊断,它正在成为各行各业的核心驱动力。然而,构建一个高效、安全且负责任的生成式AI系统并非易事。本文将带你从零开始,逐步完成一个完整…...
Windows 10更新失败解决方法
在我们使用 Windows 时的时候,很多时候遇到系统更新 重启之后却一直提示“我们无法完成更新,正在撤销更改” 这种情况非常烦人,但其实可以通过修改文件的方法解决,并且正常更新到最新版操作系统 01修改注册表 管理员身份运行注…...
Windows下在IntelliJ IDEA 使用 Git 拉取、提交脚本出现换行符问题
文章目录 背景问题拉取代码时提交代码时 问题原因解决方案1.全局配置 Git 的换行符处理策略2.在 IntelliJ IDEA 中配置换行符3.使用 .gitattributes 文件 背景 在 Windows 系统下使用 IntelliJ IDEA 进行 Git 操作(如拉取和提交脚本)时,经常…...
ubuntu24.04.2 NVIDIA GeForce RTX 4060笔记本安装驱动
https://www.nvidia.cn/drivers/details/242281/ 上面是下载地址 sudo chmod x NVIDIA-Linux-x86_64-570.133.07.run # 赋予执行权限把下载的驱动复制到家目录下,基本工具准备,如下 sudo apt update sudo apt install build-essential libglvnd-dev …...
一种监控录像视频恢复的高效解决方案,从每一帧中寻找可能性
该软件旨在恢复从监控设备中删除或丢失的视频。该程序经过调整以处理大多数流行供应商的闭路电视系统中使用的专有格式,并通过智能重建引擎进行了增强,能够为监控记录提供任何通用解决方案都无法实现的恢复结果。如果不需要持续使用该软件,则…...
