news 2026/5/5 0:11:10

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
二刷 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. 边界意识:两道题都对边界的处理有严格要求,比如跳跃游戏的循环终止条件、划分字母区间的片段终点判断,边界错一步,结果就会出错。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/5 0:11:03

如何快速实现B站缓存视频转换:3个简单步骤永久保存珍贵内容

如何快速实现B站缓存视频转换&#xff1a;3个简单步骤永久保存珍贵内容 【免费下载链接】m4s-converter 一个跨平台小工具&#xff0c;将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾经遇到过这样的尴…

作者头像 李华
网站建设 2026/5/5 0:07:41

Hypergrep:现代代码搜索工具的设计原理与工程实践

1. 项目概述&#xff1a;一个为现代开发者打造的极速代码搜索工具如果你和我一样&#xff0c;每天有超过一半的时间是在代码仓库里“寻宝”——寻找某个函数定义、追踪某个变量的所有引用、或者在一堆日志文件中定位特定的错误信息——那么你一定对grep这个老牌工具又爱又恨。爱…

作者头像 李华
网站建设 2026/5/4 23:55:01

RetinaNet之后,One-Stage检测器如何卷出新高度?YOLOv5/v7、FCOS对比分析

RetinaNet之后&#xff1a;One-Stage检测器的技术演进与实战选型指南 在计算机视觉领域&#xff0c;目标检测技术始终处于快速迭代的前沿。2017年RetinaNet的横空出世&#xff0c;通过创新的Focal Loss机制解决了长期困扰单阶段检测器的样本不平衡问题&#xff0c;首次让One-St…

作者头像 李华
网站建设 2026/5/4 23:53:50

java微服务项目的架构和链路串联

目录 Java 微服务项目&#xff1a;架构、链路串联、常见问题 & 解决方案 一、先搞懂&#xff1a;Java 微服务标准架构&#xff08;企业通用&#xff09; 1. 接入层 2. 业务服务层&#xff08;核心&#xff09; 3. 基础设施层&#xff08;所有服务共用&#xff09; 4.…

作者头像 李华