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

12.将 x 减到 0 的最小操作数 | 滑动窗口+正难则反

目录

1. 题目解析

2. 算法原理

2.1 正难则反的转换

2.2 滑动窗口解法

3. 编写代码

4. 总结


1. 题目解析

题目:1658. 将 x 减到 0 的最小操作数

链接:1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)

题意:给你一个整数数组nums和一个整数x,每一次操作时,你应当移除数组nums最左边或最右边的元素,然后从x中减去该元素的值。请注意,需要修改数组以供接下来的操作使用。如果可以将x恰好减到 0,返回最小操作数;否则,返回 -1。

示例 1

输入:nums = [1,1,4,2,3], x = 5

输出:2

解释:最佳解决方案是移除后两个元素,将 x 减到 0。

示例 2

输入:nums = [5,6,7,8,9], x = 4

输出:-1

(注释:从数组两端移除元素,x 的变化过程,比如示例 1 中移除最后两个元素[2,3],x 从 5→3→0,共 2 次;另一种尝试移除前两个[1,1],x 5→4→3,不是最优。)

2. 算法原理

核心思路:正难则反 + 滑动窗口

2.1 正难则反的转换

我们需要让x减到 0,相当于从数组的两端移除元素,使这些元素的和等于x。反过来想:如果我们能找到一个中间子数组,其和为sum - xsum是数组总和),那么剩下的元素(两端的)就是需要移除的,且移除的数量最少。

  • 设数组总和为sum,目标子数组的和为target = sum - x

  • 我们需要找到最长的子数组,其和等于target。这样,移除的元素数量(操作数)就是n - lenn是数组长度,len是子数组长度)。

(数组整体和为sum,中间子数组和为target = sum - x,则两端移除的元素和为x。要最小化操作数,即最大化中间子数组的长度len,操作数为n - len。)

2.2 滑动窗口解法

滑动窗口用于找最长子数组和为 target​ 的情况,步骤如下:

  1. 初始化left = 0, right = 0(窗口左右边界),tmp = 0(窗口内元素和)。

  2. 右边界right右移,进窗口tmp += nums[right]

  3. tmp > target,则左边界left右移,出窗口tmp -= nums[left++],直到tmp <= target

  4. tmp == target,更新最大长度ret = Math.max(ret, right - left + 1)

3. 编写代码

class Solution { public int minOperations(int[] nums, int x) { int sum = 0; for (int a : nums) sum += a; int target = sum - x; // 处理细节:如果target小于0,说明无法通过移除两端元素让x到0 if (target < 0) return -1; int ret = -1; for (int left = 0, right = 0, tmp = 0; right < nums.length; right++) { tmp += nums[right]; // 进窗口 while (tmp > target) { // 判断:窗口和超过target,需要缩小窗口 tmp -= nums[left++]; // 出窗口 } if (tmp == target) { ret = Math.max(ret, right - left + 1); // 更新最长子数组长度 } } if (ret == -1) return ret; // 没找到符合条件的子数组 else return nums.length - ret; // 操作数 = 总长度 - 最长子数组长度 } }

4. 总结

这道题的关键是转换思路:将“两端移除元素使和为 x”转化为“中间子数组和为 sum - x”,再用滑动窗口找最长子数组。需要注意处理target < 0的边界情况,以及最终操作数的计算(n - ret)。

(这道题最阴险的就是他需要你维护的滑动窗口是需要你画图转换得出的;其实比之前的题来说就多了一步转换罢了~)

http://www.cnnetsun.cn/news/2687973.html

相关文章:

  • 2026最新b站字幕导出方法:手把手教你一键提取字幕
  • 2026哔哩哔哩字幕提取工具推荐:手把手教你一键提取B站视频字幕
  • Android入门学习基础分享
  • NBTExplorer:可视化编辑Minecraft游戏数据的完整指南
  • Windows NAS搭建避坑实录:搞定中文乱码、电视访问和远程控制这三大‘天坑’
  • 别再死记硬背公式了!用Python+TensorFlow手把手图解点积注意力(Dot-Product Attention)
  • Instant-NGP实战:用多分辨率哈希编码5分钟搞定你的第一个NeRF模型
  • ViGEmBus:彻底解决Windows游戏手柄兼容性问题的终极方案
  • 时尚租赁公司如何用AI聊天机器人打造对话式增长引擎
  • android app开始开发定向评论功能
  • 2026爬虫实战:搞定TLS指纹与行为检测,Python采集破局指南
  • Cocos2d-x 4.0塔防实战:别再死记硬背了!用plist和xml文件管理游戏数据才是王道
  • 避坑指南:Unity集成海康SDK时,NET_DVR_PTZControlWithSpeed_Other接口的这几个参数千万别设错
  • 紫光同创FPGA DDR3实战:解析AXI4与APB接口,并编写自定义读写测试模块
  • 3步解锁QQ音乐加密音频:QMCDecode如何让你的音乐收藏重获自由?
  • 如何解决缺少特定算法思维的问题?
  • 基于AI智能体的YouTube视频自动摘要系统:从原理到实践
  • 区块链如何为AI构建可信基础设施:从数据溯源到智能协作
  • 原神帧率解锁终极指南:5分钟突破60帧限制,实现120帧丝滑体验
  • DCRNN交通流预测PyTorch工程:含训练/推理/评估全流程代码与预训练结果
  • 别再用记事本写代码了!手把手教你用VSCode配置Cocos Creator 3.x的TypeScript开发环境
  • 别再死磕传统LOD了!用UE5的Nanite做超大规模场景,我的踩坑与优化心得
  • 3步搞定百度网盘高速下载:网盘直链下载助手的终极解决方案
  • Windows窗口置顶解决方案:AlwaysOnTop 深度解析与实战指南
  • STM32F103C8T6软I²C驱动AT24C16 EEPROM的完整Keil工程,含页写/随机读/多地址支持
  • 儿童护眼灯对眼睛有伤害吗?挑错护眼灯危害视力,教你如何选择
  • 架构腐化:代码是怎么从“小甜甜“变成“牛夫人“的
  • Win Server 2019远程桌面设置详解:从单用户到多用户,再到连接数限制的完整策略
  • 保姆级教程:用Python+Librosa从零搭建一个简易无人机声纹识别模型(附代码)
  • 别再死记硬背匈牙利算法了!用这3道LeetCode/洛谷经典题,带你彻底搞懂二分图匹配