

文章目录
-
- 摘要
- 描述
- 题解答案(核心思路)
- [题解答案(Swift 可运行 Demo)](#题解答案(Swift 可运行 Demo))
- 题解代码分析
-
- [1. 为什么一定要排序?](#1. 为什么一定要排序?)
- [2. 双指针的意义](#2. 双指针的意义)
- [3. 关键判断逻辑](#3. 关键判断逻辑)
- [4. 为什么不会漏解?](#4. 为什么不会漏解?)
- 示例测试及结果
-
- [示例 1](#示例 1)
- [示例 2](#示例 2)
- 自定义测试
- 实际场景结合
-
- [1. 资源分配问题](#1. 资源分配问题)
- [2. 人力与任务匹配](#2. 人力与任务匹配)
- [3. 面试中的信号题](#3. 面试中的信号题)
- 时间复杂度
- 空间复杂度
- 总结
摘要
LeetCode 455 是一道非常经典的贪心入门题。
题目本身不复杂,但如果你第一次写,很容易陷入一种纠结:
- 是不是要给胃口最大的孩子最大的饼干?
- 要不要试所有组合?
- 会不会分配错了,后面没法满足更多孩子?
其实这道题的核心只有一句话:
用最小的资源,优先满足最容易满足的人。
一旦想通这一点,代码就会变得非常干净,而且效率也很高。

描述
你有两组数据:
g[i]:第i个孩子的胃口值(最小需要多大的饼干)s[j]:第j块饼干的尺寸
规则很简单:
- 一个孩子 最多只能拿一块饼干
- 一块饼干 只能给一个孩子
- 只有当
s[j] >= g[i],这个孩子才会满足
你的目标不是让所有孩子都满足,而是:
尽可能多地满足孩子,返回最大数量
题解答案(核心思路)
贪心策略怎么定?
这道题的贪心策略其实非常直觉化:
-
先排序
- 孩子的胃口从小到大排
- 饼干的尺寸从小到大排
-
用最小的饼干,去尝试满足胃口最小的孩子
-
如果当前饼干满足不了这个孩子,那它也一定满足不了胃口更大的孩子,直接丢弃
-
如果能满足,就计数 +1,同时换下一个孩子和下一块饼干
为什么这个策略是对的?
因为:
- 胃口小的孩子选择空间最大
- 小饼干是"最稀缺"的资源
- 如果你用大饼干去喂小胃口的孩子,很可能会浪费掉大饼干
这和现实生活其实一模一样。

题解答案(Swift 可运行 Demo)
swift
class Solution {
func findContentChildren(_ g: [Int], _ s: [Int]) -> Int {
// 1. 排序
let children = g.sorted()
let cookies = s.sorted()
var childIndex = 0
var cookieIndex = 0
var result = 0
// 2. 双指针遍历
while childIndex < children.count && cookieIndex < cookies.count {
if cookies[cookieIndex] >= children[childIndex] {
// 当前饼干可以满足当前孩子
result += 1
childIndex += 1
cookieIndex += 1
} else {
// 饼干太小,换一块更大的
cookieIndex += 1
}
}
return result
}
}
题解代码分析
1. 为什么一定要排序?
swift
let children = g.sorted()
let cookies = s.sorted()
排序之后有两个好处:
- 胃口小的孩子排在前面,优先满足
- 饼干尺寸从小到大,避免浪费大饼干
如果不排序,你就很难保证当前的分配是"最省资源"的。
2. 双指针的意义
swift
var childIndex = 0
var cookieIndex = 0
这两个指针分别表示:
childIndex:当前要尝试满足的孩子cookieIndex:当前拿来用的饼干
指针只往前走,不回退,这也是贪心算法的典型特征。
3. 关键判断逻辑
swift
if cookies[cookieIndex] >= children[childIndex]
- 满足:说明这块饼干是"刚刚好或更大",直接用
- 不满足:说明这块饼干太小,留着也没用,换下一块
这里有个非常重要但容易忽略的点:
如果当前饼干满足不了当前孩子,那它一定满足不了后面的孩子。
4. 为什么不会漏解?
因为:
- 每个孩子只会尝试一次
- 每块饼干只会使用或丢弃一次
- 没有回头路,但这是正确的回头路不需要走
示例测试及结果
示例 1
swift
let solution = Solution()
print(solution.findContentChildren([1,2,3], [1,1]))
输出:
text
1
解释过程:
- 饼干:[1,1]
- 孩子胃口:[1,2,3]
- 只能满足胃口为 1 的孩子
示例 2
swift
print(solution.findContentChildren([1,2], [1,2,3]))
输出:
text
2
解释过程:
- 饼干足够
- 每个孩子都能被满足
自定义测试
swift
print(solution.findContentChildren([2,3,4], [1,2,3]))
结果:
text
2
解释:
- 胃口 2 用饼干 2
- 胃口 3 用饼干 3
- 胃口 4 无法满足
实际场景结合
这道题的思路在真实世界中非常常见。
1. 资源分配问题
- 带宽分配
- 内存分配
- 任务调度
本质都是:
用有限资源,尽量满足更多请求
2. 人力与任务匹配
比如:
- 初级任务给初级工程师
- 高难度任务留给高级工程师
如果你反过来分配,很容易"浪费能力"。
3. 面试中的信号题
这道题经常被用来考:
- 是否理解贪心的正确性
- 是否能写出简洁、不绕弯的代码
- 是否能解释为什么这样贪是对的
时间复杂度
- 排序:
O(n log n) - 双指针遍历:
O(n)
整体时间复杂度:
text
O(n log n)
空间复杂度
- 排序需要额外空间(取决于语言实现)
- 指针变量是常量级
空间复杂度:
text
O(1)(忽略排序带来的额外空间)
总结
LeetCode 455 是一道非常值得反复体会的贪心题:
- 思路简单
- 逻辑清晰
- 非常贴近真实世界的决策方式
如果你能把这道题讲清楚,说明你已经不只是"刷题",而是在真正理解算法的决策逻辑。