算法系列——分发饼干(Assign Cookies)

本文介绍了LeetCode上的分发饼干问题,每个孩子有最小需求的饼干大小,目标是最大化满足的孩子数量。通过贪心策略,优先满足需求较小的孩子,从而达到全局最优解。文章提供了详细的解题思路和程序实现。

题目描述

题目链接:https://leetcode-cn.com/problems/assign-cookies/
Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie. Each child i has a greed factor gi, which is the minimum size of a cookie that the child will be content with; and each cookie j has a size sj. If sj >= gi, we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number.

Note:
You may assume the greed factor is always positive.
You cannot assign more than one cookie to one child.

Example 1:

Input: [1,2,3], [1,1]
Output: 1

Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. 
And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content.
You need to output 1.

Example 2:

Input: [1,2], [1,2,3]
Output: 2

Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. 
You have 3 cookies and their sizes are big enough to gratify all of the children, 
You need to output 2.

解题思路

典型贪心算法,小饼干先喂饱小胃口,局部最优 推到全局最优。

程序实现

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        //排序,贪心 小饼干优先满足小的
        Arrays.sort(g);
        Arrays.sort(s);
        int index=0;
        for(int i=0;i<s.length;i++){
            if(index<g.length&&s[i]>=g[index]){
                index++;
            }
        }
        return index;
    }
}
<think> 首先,用户查询是:“我想查找使用Python实现贪心算法解决分饼干问题的相关内容”。这是一个关于贪心算法在分饼干问题中的应用的具体请求。 从系统指令来看,我需要遵循: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 参考提供的引用内容(引用[1]、[2]、[3]、[4]、[5]),但要根据用户的真实需求调整。 提供的引用内容是关于贪心算法解决分饼干问题的: - 引用[1]解释了贪心算法的核心思想:坚持当下的最好选择,优先满足最容易满足的孩子来最大化满足数量。 - 引用[2]描述了贪心算法的基本概念和适用条件(无后效性),并提到分发饼干问题。 - 引用[3]讨论了贪心算法的适用性和挑战。 - 引用[4]给出了具体的Python代码实现。 - 引用[5]提供了另一个类似的Python代码实现。 用户的需求是“Python实现贪心算法解决分饼干问题”,所以我应该重点放在Python代码的实现上,并解释贪心算法的应用。 结构我的回答: 1. **介绍问题**:简要描述分饼干问题(Assign cookies problem),类似于LeetCode 455题。 2. **解释贪心算法思路**:说明贪心算法的核心思想,如何应用于这个问题。 3. **提供Python代码**:使用给定的引用中的代码作为参考。引用[4]和[5]都有代码,我应该整合或选择一个清晰的版本。 4. **解释代码步骤**:逐步解释代码的逻辑。 5. **添加引用标识**:在引用内容的末尾自然地添加[^n]。 6. **生成相关问题**:在最后添加相关问题部分。 7. **使用中文**:整个回答用中文。 确保行内数学表达式:问题中可能涉及比较胃口和饼干大小,但不需要复杂数学,所以可能只是简单提到如胃口值g[i]和饼干大小s[j],使用$g[i]$或$s[j]$格式。 独立公式:可能不需要,因为问题不涉及复杂的数学公式。 Python代码块:使用代码块展示代码。 回答结构: - 开头:介绍分饼干问题。 - 主体: - 解释贪心策略。 - 展示Python代码。 - 解释代码。 - 结尾:总结或添加引用。 - 然后:生成相关问题。 引用标识:基于提供的引用: - 引用[1]:贪心核心思想。 - 引用[2]:贪心算法定义和特性。 - 引用[3]:贪心适用性和挑战。 - 引用[4]:代码实现。 - 引用[5]:另一个代码实现。 在回答中,当我引用这些内容时,在段落末尾添加[^1]、[^2]等。 例如,在解释贪心思想时提到引用[1],在讨论无后效性时提到引用[2],在展示代码时使用引用[4]或[5]。 代码选择:引用[4]和[5]的代码类似,都是排序然后双指针。引用[4]更简洁,所以我可以用那个: ```python class Solution: def findContentChildren(self, g: List[int], s: List[int]) -> int: g.sort() s.sort() count = 0 i = 0 # 指向孩子 j = 0 # 指向饼干 while i < len(g) and j < len(s): if g[i] <= s[j]: count += 1 i += 1 j += 1 else: j += 1 return count ``` 解释步骤: 1. 排序孩子胃口和饼干大小。 2. 使用双指针遍历,如果饼干满足当前孩子,则计数增加并移动两个指针;否则只移动饼干指针。 3. 贪心策略:小饼干优先满足小胃口孩子。 生成相关问题: 基于用户查询,可能的后续问题: 1. 贪心算法在分饼干问题中的时间复杂度? 2. 如何证明贪心算法的正确性? 3. 其他贪心算法问题(如分糖果)的比较? 4. 贪心算法的局限性? 5. 优化或变种? 最终回答格式: - 标题或开头明确主题。 - 分步骤解释。 - 代码块。 - 解释。 - 自然添加引用。 - 相关问题部分。 </think> 以下是针对您查询的“使用Python实现贪心算法解决分饼干问题”的详细解答。我将基于您提供的引用内容(引用[1]-[5]),结合贪心算法的核心思想和Python实现,逐步解释问题背景、贪心策略、代码实现及分析。分饼干问题(LeetCode 455题)的目标是:给定一组孩子的胃口值$g$和一组饼干的大小$s$,每个孩子最多只能分到一块饼干,且饼干大小需大于等于孩子的胃口值,求最多能满足的孩子数量。贪心算法通过“坚持当下的最好选择”来高效解决此问题[^1]。 ### 问题背景与贪心策略 贪心算法的核心思想是:在每一步决策中,选择当前最优的解,而不考虑后续影响。这适用于分饼干问题,因为问题具有“无后效性”——当前决策不影响后续状态[^2]。具体策略如下: 1. **贪心选择**:优先用最小的饼干满足胃口最小的孩子。这样可以最大化利用小饼干,避免浪费在胃口大的孩子身上。 2. **排序是关键**:将孩子胃口$g$和饼干大小$s$排序后,可以高效匹配。 3. **局部最优到全局最优**:每一步确保当前饼干分配给最易满足的孩子,最终积累为全局最优解(最多满足孩子数)。贪心策略的正确性需要证明,但对于此问题已被广泛验证[^3]。 ### Python代码实现 以下是标准Python实现代码,源自引用[4]和[5]的整合版本。代码使用双指针遍历排序后的列表,时间复杂度为$O(n \log n)$(主要由排序决定),空间复杂度为$O(1)$。 ```python def findContentChildren(g, s): """ 贪心算法解决分饼干问题 :param g: List[int], 孩子的胃口值列表 :param s: List[int], 饼干的大小列表 :return: int, 最多满足的孩子数量 """ g.sort() # 孩子胃口从小到大排序 s.sort() # 饼干大小从小到大排序 count = 0 # 满足孩子的计数器 i = 0 # 指针,指向当前孩子 j = 0 # 指针,指向当前饼干 # 双指针遍历列表 while i < len(g) and j < len(s): if g[i] <= s[j]: # 当前饼干满足孩子:计数增加,移动孩子和饼干指针 count += 1 i += 1 j += 1 else: # 饼干太小,无法满足当前孩子:只移动饼干指针(丢弃小饼干) j += 1 return count ``` ### 代码解释与步骤分析 1. **排序阶段**: - `g.sort()` 和 `s.sort()`:将孩子胃口$g$和饼干大小$s$升序排序。这是贪心策略的基础,确保“当下最好选择”[^1]。例如,输入 $g = [1, 2, 3], s = [1, 1]$,排序后更易匹配。 2. **双指针遍历**: - 初始化指针 `i` (孩子) 和 `j` (饼干) 为0。 - 循环条件 `while i < len(g) and j < len(s)`:确保遍历所有可能匹配。 - **满足条件**:如果 $g[i] \leq s[j]$(饼干满足孩子胃口),则: - `count += 1`:满足孩子数增加。 - `i += 1` 和 `j += 1`:移动指针到下一位(孩子已满足,饼干被消耗)。 - **不满足条件**:如果 $g[i] > s[j]$(饼干太小),则: - `j += 1`:仅移动饼干指针,丢弃当前小饼干(因为它无法满足当前或胃口更大的孩子)。 3. **返回值**: - `return count`:最终返回满足的孩子数。 贪心策略的正确性在于:排序后,小饼干优先满足小胃口孩子,避免“大饼干浪费在小胃口孩子”,从而最大化满足数[^4]。 ### 示例运行 测试代码: ```python # 测试用例 g = [1, 2, 3] # 孩子胃口 s = [1, 1] # 饼干大小 print(findContentChildren(g, s)) # 输出: 1(只能满足胃口1的孩子) g = [1, 2] s = [1, 2, 3] print(findContentChildren(g, s)) # 输出: 2(所有孩子均满足) ``` 贪心算法的效率高,但需注意:它依赖于排序的正确性,且仅适用于此问题特性(无后效性)。在实践中,贪心算法可能不适用于更复杂的约束,需要结合问题建模[^3]。 ### 总结 贪心算法通过排序和双指针高效解决了分饼干问题,体现了“坚持当下最优选择”的原则。Python实现代码简洁,适用于类似分配问题。但贪心策略的证明是关键,否则可能失效[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值