力扣刷题 455.分发饼干

博客围绕LeetCode中给孩子分饼干的题目展开。题干是每个孩子有胃口值,每块饼干有尺寸,要尽可能满足更多孩子。解题思路运用贪心算法,即选择每一阶段的局部最优以达全局最优。对饼干和胃口数组排序,介绍了孩子遍历和饼干遍历两种方式,还提醒注意数组越界问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题干

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

示例 1:

输入: g = [1,2,3], s = [1,1]
输出: 1
解释: 
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。

示例 2:

输入: g = [1,2], s = [1,2,3]
输出: 2
解释: 
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.

解题思路

这道题的思路用到了贪心算法,在具体阐述之前,让我们看看何为贪心算法。

贪心算法的本质是选择每一阶段的局部最优,从而达到全局最优

比如从一叠钞票中选取10张,目标是拿最多的钱,那么每次策略就是拿最高金额的纸币,从而达到全局最优。

如何判断这道题目能够使用贪心算法?

动手模拟,举反例,如果没有反例就可以使用。


我们的思路是每次给饼干都尽可能把小饼干喂给胃口小的小孩,充分利用资源。

我们对饼干数组和胃口数组都进行从小到大的排序

本题遍历孩子和饼干的视角都可以,但是饼干的时间复杂度更低。

当我们用孩子遍历时,视角是每遍历一个孩子,不停往更大的饼干找,直到饼干大于等于孩子的胃口。当饼干使用完了,就返回值。 注意不需要建立变量来记录投喂数,孩子的索引就代表投喂数

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        int i = 0;
        //对饼干大小数组排序
        sort(s.begin(),s.end());
        sort(g.begin(),g.end());
        int j = 0;
        //遍历孩子
        for(; i < g.size(); i++){
            //从最小的饼干开始给
            while(j < s.size() && s[j] < g[i]){
                j++;
            }
            if(j == s.size()){
                return i;
            }
            j++;
        }
    return i;
    }
};

用饼干遍历的做法类似双指针,用到了两个索引。但不是严格意义双指针,因为双指针的两个索引是在同一个数组。这里只是用到了类似的思想

快指针移动寻找可以使用的饼干

慢指针指向未吃饭孩子中胃口最小的孩子,只有饼干大小大于孩子胃口,慢指针才会指向下一个孩子 

循环的本质就是索引的更新,就关键的就是索引。

当我们的判断条件中有存在会改变的量,就需要格外注意,添加限制条件,避免数组越界等问题

数组越界条件书写的顺序要注意,要在可能发生数组越界的地方的前面。

完整代码如下

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        int index = 0;//索引
        //从小到大排序两个数组
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        for(int j = 0; j < s.size(); j++){//饼干遍历
            //避免index的值超过数组边界,造成数组越界
            if(index < g.size() && s[j] >= g[index]){
                index++;   
            }
        }
        return index;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值