Leetcode 刷题 - 贪心思想(day1)_分配饼干

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 + " 个孩子");
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Janson666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值