贪心算法:分配问题
记录自己的刷题过程,答案参考过多种题解。
如有疏漏感谢指正!
455. 分发饼干 (Easy)
有一群孩子和一堆饼干,每个孩子有一个饥饿度,每个饼干都有一个大小。每个孩子只能吃最多一个饼干,且只有饼干的大小大于孩子的饥饿度时,这个孩子才能吃饱。求解最多有多少孩子可以吃饱。
A. 分发饼干的贪心思想
-
用 最小 的饼干来满足孩子的最小需求。
-
局部最优体现在,用最小的饼干满足了需求小的人,就可以用更大的饼干满足需求大的人。避免出现 “大饼干、低需求” 的浪费现象。
-
全局最优体现在,分配给每个人的饼干 数量 达到最大化,即喂饱尽可能多的小孩。
B. 具体实现
-
要实现 “小饼干、低需求” ,就需要得到需求和饼干的大小关系。
-
一个便捷的方法就是把孩子和饼干分别 排序 。 这样我们就可以从需求最小的孩子和最小的饼干出发,计算有多少个对子可以满足条件。
-
从小到大按顺序遍历的好处就是,不能满足排在前面孩子A的需求的饼干,必定不能满足排在孩子A后面的孩子的需求,因此 之前排除掉的饼干就可以不考虑 ,只从可以满足孩子A需求的 后一个饼干 开始继续判断。
C. 思考
-
用 while() 进行判断循环的优势是,可以将 循环变量 重复利用。既可以把A变量当作循环用的变量,也可以用作内部计数变量,根据情况判断变量是否增 or 减。
-
while() 中的判断语句,&& 或 || 的使用很灵活,结合题意多思考,常会写出很妙的算法。
-
把计数变量和循环变量、数组下标变量联系起来,而不是孤立的设置计数变量单独使用。
D. 代码实现
// 优先考虑饼干,小饼干先喂饱小胃口
public int findContentChildren(int[] g, int[] s) {
int child = 0, cookie = 0;
Arrays.sort(g); //先将饼干和孩子所需大小都进行排序
Arrays.sort(s);
while (child < g.length && cookie < s.length) { //当其中一个遍历完就结束
if (g[child] <= s[cookie]) { //当用当前饼干可以满足当前孩子的需求,可以满足的孩子数量+1
++child;
}
++cookie; // 饼干只可以用一次,因为饼干如果小的话,就是无法满足被抛弃,满足的话就是被用了
}
return child;
}