力扣 455 分发饼干
全部刷题与学习记录
原题目
题目地址: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;
}
好的解法
【代码随想录】大佬给出了另外一种贪心解法,可能这才是正确的贪心思想:局部最优是每次将大饼干分给胃口最大的,保证胃口大的孩子拿到大饼干;全局最优是最后尽可能多的孩子被满足。我的思路其实跟大佬倒过来了,我就是先用最小的饼干满足胃口最小的孩子。
关于局部最优与全局最优,大佬在【代码随想录】关于贪心算法,你该了解这些!解释得很清楚了,上一个传送门