分饼干

力扣题目链接(opens new window)

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

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

提示:

  • 1 <= g.length <= 3 * 10^4
  • 0 <= s.length <= 3 * 10^4
  • 1 <= g[i], s[j] <= 2^31 - 1

思路

按照示例1的做法可以得知,我们可以不使用所有的饼干,除非一块饼干能够大于等于当前小孩的胃口,不然饿死都不给你吃

上述逻辑可以总结为:

要满足更多的孩子,就不能浪费饼干(尺寸),饼干尺寸必须严格匹配孩子的胃口。

其实大饼干既可以给小胃口的孩子吃也可以给大胃口的孩子吃,但饼干还有剩的,有可能还有留给小胃口的,使用应该优先满足大胃口的孩子

局部最优解:大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个

全局最优解:喂饱尽可能多的小孩

根据以上分析,尝试贪心策略

解题步骤如下:

​ 1、先分别对胃口数组饼干数组进行排序

​ 2、先遍历胃口,再遍历饼干,如果饼干大于胃口,记录结果并同时移动胃口和饼干的下标(注意,这个需求注定了在代码实现时不好用双层for循环,会把逻辑搞复杂)

代码

基于解题步骤,代码步骤如下:

​ 1、对胃口数组饼干数组进行排序

​ 2、因为不好用双层for来实现遍历,所以使用自减的方式遍历饼干(即通过对一个下标变量的控制,来遍历对应的数据结构),所以要定义一个饼干数组的遍历下标index,还有结果收集变量res

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        //先对胃口和饼干进行排序
        sort(g.begin(), g.end());
        sort(s.begin(), s.end());

        //定义变量指向饼干数组遍历值下标
        int index = s.size() - 1;
        int res = 0;//记录结果
        //遍历胃口,倒序
        for(int i = g.size() - 1; i >= 0; --i){
            if(index >= 0 && s[index] >= g[i]){//使用自减方式遍历
                index--;
                res++;
            }
        }
        return res;
    }
};
疑惑

说实话还是没明白贪心的逻辑是如何举反例证明可行的,以后有新理解再补充

(太晚了睡了,23:57)