1. 分配饼干
455. Assign Cookies (Easy)
Input: grid[1,3], size[1,2,4]
Output: 2
题目描述:每个孩子都有一个满足度 grid,每个饼干都有一个大小 size,只有饼干的大小大于等于一个孩子的满足度,该孩子才会获得满足。求解最多可以获得满足的孩子数量。
- 1.给一个孩子的饼干应当尽量小并且又能满足该孩子,这样大饼干才能拿来给满足度比较大的孩子。
- 2.因为满足度最小的孩子最容易得到满足,所以先满足满足度最小的孩子。
在以上的解法中,我们只在每次分配时饼干时选择一种看起来是当前最优的分配方法,但无法保证这种局部最优的分配方法最后能得到全局最优解。我们假设能得到全局最优解,并使用反证法进行证明,即假设存在一种比我们使用的贪心策略更优的最优策略。如果不存在这种最优策略,表示贪心策略就是最优策略,得到的解也就是全局最优解。
证明:假设在某次选择中,贪心策略选择给当前满足度最小的孩子分配第 m 个饼干,第 m 个饼干为可以满足该孩子的最小饼干。假设存在一种最优策略,可以给该孩子分配第 n 个饼干,并且 m < n。我们可以发现,经过这一轮分配,贪心策略分配后剩下的饼干一定有一个比最优策略来得大。因此在后续的分配中,贪心策略一定能满足更多的孩子。也就是说不存在比贪心策略更优的策略,即贪心策略就是最优策略。
算法源码
package greedyAlgorithm;
import java.util.Arrays;
/**
* 1. 分配饼干
* 455. Assign Cookies (Easy)
*
* @Author Janson
* @Date 2022/3/7 11:01
* @Version 1.0
*
* Input: grid[1,3], size[1,2,4]
* Output: 2
* 题目描述:每个孩子都有一个满足度 grid,每个饼干都有一个大小 size,
* 只有饼干的大小大于等于一个孩子的满足度,该孩子才会获得满足。求解最多可以获得满足的孩子数量。
*
* 1.给一个孩子的饼干应当尽量小并且又能满足该孩子,这样大饼干才能拿来给满足度比较大的孩子。
* 2.因为满足度最小的孩子最容易得到满足,所以先满足满足度最小的孩子。
*
* 在以上的解法中,我们只在每次分配时饼干时选择一种看起来是当前最优的分配方法,
* 但无法保证这种局部最优的分配方法最后能得到全局最优解。我们假设能得到全局最优解,
* 并使用反证法进行证明,即假设存在一种比我们使用的贪心策略更优的最优策略。如果不存在这种最优策略,
* 表示贪心策略就是最优策略,得到的解也就是全局最优解。
*
* 证明:假设在某次选择中,贪心策略选择给当前满足度最小的孩子分配第 m 个饼干,
* 第 m 个饼干为可以满足该孩子的最小饼干。
* 假设存在一种最优策略,可以给该孩子分配第 n 个饼干,并且 m < n。我们可以发现,
* 经过这一轮分配,贪心策略分配后剩下的饼干一定有一个比最优策略来得大。因此在后续的分配中,
* 贪心策略一定能满足更多的孩子。也就是说不存在比贪心策略更优的策略,即贪心策略就是最优策略。
*/
public class AssignCookies {
public static void main(String[] args) {
int[] gird = new int[]{1,2,3,5};
int[] size = new int[]{1,1,4,6,3};
//1.排序
Arrays.sort(gird);
Arrays.sort(size);
int gi = 0,si = 0;
//2.遍历比较,求满足孩子的个数
while (gi<gird.length && si < size.length){
if (gird[gi]<=size[si]){
//新增了输出 那个小饼干 满足了 那位小朋友
System.out.println(size[si] + " 饼干满足了 " + gird[gi] + "小朋友,他很开心。");
gi++;
}
si++;
}
//3.得出结果,刚开始想的加一个变量 count 计数,但是的确没必要,因为对 孩子数组排序了
//所以直接输出孩子数组的下标,就可以得到满足的孩子个数
System.out.println("官方答案给的while循环答案:---总共满足了 " + gi + " 个孩子");
System.out.println("=========================================================");
//网上给的 while 循环,我想的是用 for循环,其实都一样,看个人情况,时间复杂度应该是一样的
//在展示自己写的实现时,需要重置一下参数
gi = 0;
si = 0;
for (; gi < gird.length && si<size.length; ) {
if (gird[gi]<=size[si]){
System.out.println(size[si] + " 饼干满足了 " + gird[gi] + "小朋友,他很开心。");
gi++;
}
si++;
}
System.out.println("自己写的for循环答案:---总共满足了 " + gi + " 个孩子");
}
}