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

二刷 LeetCode:两道经典贪心题复盘

目录

一、LeetCode 45. 跳跃游戏 II

题目回顾

核心思路(正向贪心)

Java 实现代码

二刷反思

二、LeetCode 763. 划分字母区间

题目回顾

核心思路(两次遍历 + 边界扩展)

Java 实现代码

二刷反思

三、贪心算法的通用复盘


二刷贪心算法专题,把两道经典中等题「跳跃游戏 II」和「划分字母区间」重新啃了一遍。比起第一次的懵懵懂懂,这次明显对贪心的核心思想有了更透彻的理解,也想把复盘整理成博客,帮自己沉淀下来,也给同在路上的伙伴们一点参考。


一、LeetCode 45. 跳跃游戏 II

题目回顾

给定一个非负整数数组nums,你最初位于数组的第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用最少的跳跃次数到达数组的最后一个位置。题目保证你一定可以到达终点。

核心思路(正向贪心)

这道题的贪心核心是:不需要知道每一步具体跳到哪个位置,只需要维护当前跳跃能覆盖的区间,在区间内找到下一步能跳得最远的位置,以此减少跳跃次数

  • 维护三个变量:
    • step:记录跳跃次数,初始为 0
    • currentEnd:当前这一跳能到达的最远边界
    • maxReach:在当前区间内遍历,更新能到达的下一个最远边界
  • 遍历数组(注意不需要遍历到最后一个元素):
    1. 更新maxReach = max(maxReach, i + nums[i])
    2. 当遍历到currentEnd时,说明当前区间已经遍历完毕,必须进行下一次跳跃:step++,同时更新currentEnd = maxReach
    3. 如果currentEnd已经能到达终点,直接提前结束

Java 实现代码

java

运行

public int jump(int[] nums) { int n = nums.length; if (n <= 1) return 0; int step = 0; int currentEnd = 0; int maxReach = 0; for (int i = 0; i < n - 1; i++) { maxReach = Math.max(maxReach, i + nums[i]); if (i == currentEnd) { step++; currentEnd = maxReach; if (currentEnd >= n - 1) break; } } return step; }

二刷反思

  • 第一次写的时候,很容易陷入「找具体路径」的误区,想着用动态规划记录每个位置的最少跳跃次数,结果写出来的代码又复杂又低效。
  • 这次才真正理解:贪心的精髓是放弃局部最优路径的细节,只保留全局最优的边界信息。时间复杂度直接从 O (n²) 降到了 O (n),空间复杂度 O (1),完美符合面试官的期望。
  • 易错点:循环条件是i < n - 1,因为最后一个位置不需要再跳一次,否则会多算一次跳跃次数。

二、LeetCode 763. 划分字母区间

题目回顾

给你一个字符串s。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。

核心思路(两次遍历 + 边界扩展)

这道题的贪心核心是:先预处理每个字符的最后出现位置,再遍历字符串动态扩展当前片段的边界,当遍历到边界时,就是一个合法的片段

  1. 预处理:第一次遍历字符串,用数组last[26]记录每个小写字母最后一次出现的下标
  2. 贪心划分:第二次遍历字符串,维护当前片段的起点start和终点end
    • 对于每个字符c,更新end = max(end, last[c - 'a'])
    • i == end时,说明当前片段已经包含了所有出现过的字符,记录片段长度end - start + 1,并更新start = i + 1

Java 实现代码

java

运行

public List<Integer> partitionLabels(String s) { List<Integer> res = new ArrayList<>(); int[] last = new int[26]; int n = s.length(); // 预处理每个字符的最后出现位置 for (int i = 0; i < n; i++) { last[s.charAt(i) - 'a'] = i; } int start = 0; int end = 0; for (int i = 0; i < n; i++) { end = Math.max(end, last[s.charAt(i) - 'a']); if (i == end) { res.add(end - start + 1); start = i + 1; } } return res; }

二刷反思

  • 第一次做的时候,想到了用哈希表记录最后位置,但对「动态扩展边界」的理解不够深,差点写了区间合并的复杂逻辑。
  • 这次才明白:贪心的关键是,当前片段的边界由已出现字符的最远位置决定,不需要额外处理区间合并,遍历过程中自然就能划分出所有合法片段。
  • 易错点:边界更新时,要一直取当前字符的最远位置,而不是只更新一次,否则会漏掉后面出现的字符。

三、贪心算法的通用复盘

这两道题看似场景不同,但底层的贪心思想高度一致:

  1. 放弃局部细节,聚焦全局最优:不纠结每一步的具体选择,只维护能影响后续决策的关键边界信息
  2. 预处理 + 单次遍历:先通过一次遍历拿到关键信息(比如最远位置、最大边界),再用一次遍历完成贪心决策,时间复杂度稳定在 O (n)
  3. 边界意识:两道题都对边界的处理有严格要求,比如跳跃游戏的循环终止条件、划分字母区间的片段终点判断,边界错一步,结果就会出错。
http://www.jsqmd.com/news/753918/

相关文章:

  • 基于MCP协议实现AI助手与Intervals任务管理的无缝集成
  • 别再只会用drop_duplicates了!Pandas duplicated()函数这5个高级用法,让你数据处理效率翻倍
  • 如何高效实现抖音内容批量下载:技术架构与实践指南
  • SQL Server RAG 笔记2:图数据库服务层与前端可视化构建
  • 视觉MoE框架ProMoE:高效图像生成与显存优化方案
  • ARM SSE-200安全架构与中断系统配置详解
  • Canon层优化Transformer:高效注意力机制实践指南
  • Java服务网格配置性能断崖式下跌?用Arthas+Prometheus定位ConfigMap热更新延迟的11ms真相
  • 别再画‘麻子脸’散点图了!用Matplotlib的gaussian_kde搞定海量数据可视化(附完整代码)
  • 从Open3D到CloudCompare:手把手教你用两种工具搞定点云距离分析(附代码对比)
  • Hypergrep:现代代码搜索工具的设计原理与工程实践
  • OpenDroneMap入门指南:如何将无人机照片转化为专业地图和3D模型?
  • 二刷 LeetCode:动态规划经典双题复盘
  • Ponimator:基于姿态识别的实时动画生成技术解析
  • 2026 杭州 GEO 优化服务商实力榜单:五大头部品牌全维度评测与选型参考 - GEO优化
  • Java虚拟线程与Project Loom深度绑定指南:从编译期协程支持到JFR事件追踪(JDK21 GA后唯一权威路径)
  • 21st.dev:社区驱动的React组件注册中心,基于shadcn/ui与Tailwind CSS
  • 掌握MECE原则:结构化思维的核心工具与实战应用
  • 基于LangChain的AI代理系统:自动化软件开发生命周期实践
  • Pandas CSV:高效数据处理与数据可视化指南
  • 视频速度控制器:重塑数字时代的高效观看体验
  • 2026年4月新发布注塑集中供料系统指南:为何信百勒Simbler成为首选 - 2026年企业推荐榜
  • 避坑指南:手把手教你用Python复现股票软件的副图指标(MA/MACD/成交量)并解决配置文件路径报错
  • 2026提货卡小程序标杆名录:武汉家政小程序制作、武汉小程序制作、武汉小程序商城开发、武汉小程序开发、武汉微信下单小程序开发选择指南 - 优质品牌商家
  • 如何快速实现B站缓存视频转换:3个简单步骤永久保存珍贵内容
  • 【C++27 constexpr 极致优化权威指南】:20年编译器专家亲授7大突破性技巧,绕过ISO WG21未公开限制
  • 2026年第二季度:大师级小提琴/天然虎纹小提琴/意大利小提琴/成人小提琴/收藏小提琴/欧料小提琴/油性漆小提琴/选择指南 - 优质品牌商家
  • 2026年泸州中蜂产卵王实力厂家盘点:蜜源蜜蜜蜂养殖家庭农场为何备受推崇? - 2026年企业推荐榜
  • 鸣潮自动化脚本终极指南:解放双手,专注游戏乐趣
  • ADAS开发避坑指南:FCW前方碰撞预警的‘不报警’条件全解析与实战标定