力扣 455 分发饼干【贪心】【局部最优】【全局最优】

65 篇文章 1 订阅

力扣 455 分发饼干

全部刷题与学习记录

【C++刷题学习笔记目录】

【C++百万并发网络通信-笔记目录】

原题目

题目地址:455. 分发饼干

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

对每个孩子 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.

考查知识点

贪心


自己的第一遍解法

提炼一下题目信息

孩子胃口g[i] {g1,g2,g3,...}
饼干尺寸s[j] {s1,s2,s3,...}
比较g1和s1,
1)g1≤s1:满足一个孩子 ->比较g2和s2
2)g1>s1:没有满足g1,继续用下一个饼干s2与g1比较

这样进行比较其实也是一种贪心,每次用最小的饼干满足胃口最小的孩子

但是这样有一个前提:g与s必须是排序之后的,这样才能保证每次比较都是最小的饼干与胃口最小的孩子进行比较。

这道题表面看起来要用两个循环嵌套,其实一个循环就足够了,只需要不断移动两个数组的取数索引就可以。

class Solution {
private:
    int count = 0;//满足的孩子数量
    int idG = 0;
    int idS = 0;
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        if (g.empty() or s.empty()) return 0;

        sort(g.begin(), g.end());
        sort(s.begin(), s.end());
        while (idG < g.size() and idS < s.size()) {
            if (g[idG] <= s[idS]) {//1)满足一个孩子,用下一块饼干与下一个孩子比较
                count++;
                idG++;
                idS++;
            }
            else//2)没有满足,用下一块饼干再来看看能否满足当前这个孩子
                idS++;
        }

        return count;
    }
};

int main() {
    Solution so;
    vector<int> g = {10,9,8,7};//如果Solution内部不排序,这样的输入会输出0,正确答案是2
    vector<int> s = {5,6,7,8};
    cout << so.findContentChildren(g, s) << endl;
}

好的解法

【代码随想录】大佬给出了另外一种贪心解法,可能这才是正确的贪心思想:局部最优是每次将大饼干分给胃口最大的,保证胃口大的孩子拿到大饼干;全局最优是最后尽可能多的孩子被满足。我的思路其实跟大佬倒过来了,我就是先用最小的饼干满足胃口最小的孩子。

关于局部最优与全局最优,大佬在【代码随想录】关于贪心算法,你该了解这些!解释得很清楚了,上一个传送门

【代码随想录】贪心算法:分发饼干

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值