贪心题目:分发饼干

文章目录

题目

标题和出处

标题:分发饼干

出处:455. 分发饼干

难度

3 级

题目描述

要求

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

每个孩子 i \texttt{i} i 都有一个胃口值 gi \texttt{gi} gi,这是能让孩子们满足胃口的饼干的最小尺寸;每块饼干 j \texttt{j} j 都有一个尺寸 sj \texttt{sj} sj。如果 sj ≥ gi \texttt{sj} \ge \texttt{gi} sj≥gi,则可以将饼干 j \texttt{j} j 分配给孩子 i \texttt{i} i,孩子 i \texttt{i} i 会得到满足。你的目标是满足最多数量的孩子,并返回这个最大值。

示例

示例 1:

输入: g = 1,2,3, s = 1,1 \texttt{g = 1,2,3, s = 1,1} g = 1,2,3, s = 1,1

输出: 1 \texttt{1} 1

解释:你有 3 \texttt{3} 3 个孩子和 2 \texttt{2} 2 块饼干, 3 \texttt{3} 3 个孩子的胃口值分别是 1 \texttt{1} 1、 2 \texttt{2} 2、 3 \texttt{3} 3。

虽然你有 2 \texttt{2} 2 块饼干,但是由于它们的尺寸都是 1 \texttt{1} 1,你只能让胃口值是 1 \texttt{1} 1 的孩子满足。

所以答案是 1 \texttt{1} 1。

示例 2:

输入: g = 1,2, s = 1,2,3 \texttt{g = 1,2, s = 1,2,3} g = 1,2, s = 1,2,3

输出: 2 \texttt{2} 2

解释:你有 2 \texttt{2} 2 个孩子和 3 \texttt{3} 3 块饼干, 2 \texttt{2} 2 个孩子的胃口值分别是 1 \texttt{1} 1、 2 \texttt{2} 2。

你有 3 \texttt{3} 3 块饼干,它们的尺寸可以让所有孩子满足。

所以答案是 2 \texttt{2} 2。

数据范围

  • 1 ≤ g.length ≤ 3 × 10 4 \texttt{1} \le \texttt{g.length} \le \texttt{3} \times \texttt{10}^\texttt{4} 1≤g.length≤3×104
  • 0 ≤ s.length ≤ 3 × 10 4 \texttt{0} \le \texttt{s.length} \le \texttt{3} \times \texttt{10}^\texttt{4} 0≤s.length≤3×104
  • 1 ≤ gi, sj ≤ 2 31 − 1 \texttt{1} \le \texttt{gi, sj} \le \texttt{2}^\texttt{31} - \texttt{1} 1≤gi, sj≤231−1

解法

思路和算法

为了使最多数量的孩子得到满足,根据贪心思想,应按照孩子的胃口递增的顺序依次满足每个孩子,对于每个孩子,选择剩余饼干中能满足该孩子的最小尺寸的饼干,理由如下。

将数组 g g g 按升序排序之后,假设存在两个相邻孩子的胃口分别是 g 1 g_1 g1 和 g 2 g_2 g2,其中 g 1 ≤ g 2 g_1 \le g_2 g1≤g2,满足这两个孩子的最小尺寸的饼干的尺寸分别是 s 1 s_1 s1 和 s 2 s_2 s2,则必有 s 1 ≤ s 2 s_1 \le s_2 s1≤s2。当满足的孩子最多时,应将 s 1 s_1 s1 给 g 1 g_1 g1,将 s 2 s_2 s2 给 g 2 g_2 g2。假设给 g 1 g_1 g1 的饼干尺寸是 s 3 s_3 s3 且 s 3 > s 1 s_3 > s_1 s3>s1,考虑以下两种情况。

  • 当 s 3 < s 2 s_3 < s_2 s3<s2 时,仍可以将 s 2 s_2 s2 给 g 2 g_2 g2,其余胃口更大的孩子的可用饼干数量不变,可以满足的孩子数量不变。

  • 当 s 3 ≥ s 2 s_3 \ge s_2 s3≥s2 时,其余胃口更大的孩子的可用饼干数量不变或减少一块,因此可以满足的孩子数量不变或减少,不可能满足更多的孩子。

因此,对于每个孩子选择剩余饼干中能满足该孩子的最小尺寸的饼干,该贪心策略可以使最多数量的孩子得到满足。

具体做法是,首先将数组 g g g 和 s s s 按升序排序,然后使用双指针遍历两个数组,对于每个 g i gi gi,找到未使用的饼干下标中满足 s j ≥ g i sj \ge gi sj≥gi 的最小下标 j j j,则 s j sj sj 可以满足 g i gi gi。由于数组 g g g 和 s s s 已经按升序排序,因此遍历数组 g g g 的顺序为孩子的胃口递增顺序,可以满足孩子的饼干的最小尺寸也是递增的,和遍历数组 s s s 的顺序相同,只要遍历两个数组各一次即可得到可以满足的孩子的最多数量。

代码

java 复制代码
class Solution {
    public int findContentChildren(int[] g, int[] s) {
        int count = 0;
        Arrays.sort(g);
        Arrays.sort(s);
        int numOfChildren = g.length, numOfCookies = s.length;
        int childIndex = 0, cookieIndex = 0;
        while (childIndex < numOfChildren && cookieIndex < numOfCookies) {
            if (g[childIndex] <= s[cookieIndex]) {
                count++;
                childIndex++;
            }
            cookieIndex++;
        }
        return count;
    }
}

复杂度分析

  • 时间复杂度: O ( m log ⁡ m + n log ⁡ n ) O(m \log m + n \log n) O(mlogm+nlogn),其中 m m m 和 n n n 分别是数组 g g g 和 s s s 的长度。两个数组排序分别需要 O ( m log ⁡ m ) O(m \log m) O(mlogm) 和 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间,排序之后使用双指针遍历两个数组需要 O ( m + n ) O(m + n) O(m+n) 的时间,因此时间复杂度是 O ( m log ⁡ m + n log ⁡ n + m + n ) = O ( m log ⁡ m + n log ⁡ n ) O(m \log m + n \log n + m + n) = O(m \log m + n \log n) O(mlogm+nlogn+m+n)=O(mlogm+nlogn)。

  • 空间复杂度: O ( log ⁡ m + log ⁡ n ) O(\log m + \log n) O(logm+logn),其中 m m m 和 n n n 分别是数组 g g g 和 s s s 的长度。两个数组排序分别需要 O ( log ⁡ m ) O(\log m) O(logm) 和 O ( log ⁡ n ) O(\log n) O(logn) 的递归调用栈空间。

相关推荐
Tisfy21 小时前
LeetCode 2472.不重叠回文子字符串的最大数目:动态规划(贪心)
动态规划·字符串·题解·贪心·dp·回文字符串
伟大的车尔尼5 天前
贪心题目:三角形的最大周长
贪心
青少儿编程课堂6 天前
贪心算法进阶:区间调度与最少资源整合解析
c++·python·算法·贪心·信息学竞赛·区间调度
伟大的车尔尼9 天前
贪心题目:保持城市天际线
贪心
a1879272183110 天前
【算法】动态规划第三篇:背包第一课——贪心之死与正序倒序开关
算法·leetcode·动态规划·贪心·dp·暴力·算法讲解
lvwangshu13 天前
P7668 [JOI 2018 Final] 团子制作 / Dango Maker 题解
动态规划·题解·贪心·性质题·思维好题
伟大的车尔尼13 天前
贪心题目:玩筹码
贪心
伟大的车尔尼14 天前
贪心题目:数组大小减半
贪心
漂流瓶jz14 天前
UVA-1609 不公平竞赛 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·链表·贪心·aoapc·算法竞赛入门经典·uva