刷题记录 贪心算法-2:455. 分发饼干

news2025/1/30 10:59:03

题目:455. 分发饼干

难度:简单

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

对每个孩子 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 * 104
  • 0 <= s.length <= 3 * 104
  • 1 <= g[i], s[j] <= 231 - 1

一、模式识别

1.贪心算法

局部最优解:找到满足胃口最小(大)的孩子的最小(大)饼干

从局部到全局:每满足一个孩子继续用剩余的饼干满足剩余的孩子

反例:想不到。。。

2.双指针

根据题干条件想到双指针并不难,其实我一开始是用双指针的思路做的:

题目条件:两个数组 + 逐个数字比大小(s[j] >= g[i]) -> 解法:双指针 

官方解法中的解释是:排序 + 双指针 + 贪心:

为了尽可能满足最多数量的孩子,从贪心的角度考虑,应该按照孩子的胃口从小到大的顺序依次满足每个孩子,且对于每个孩子,应该选择可以满足这个孩子的胃口且尺寸最小的饼干。

还给出了证明,但我觉得思路上理解起来并不难,所以证明过程不用细看

二.代码实现

1.双指针 + 从小胃口孩子开始喂(最简洁实现)

步骤:1.排序  2.双指针  3.循环数字比大小

写法有while循环写法和for循环写法,推荐while循环写法,可读性较强,

可以理解为for循环写法衍生于while循环写法

while循环写法:

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        if not s:
            return 0
        m, n = len(g), len(s)
        g.sort()
        s.sort()
        i, j = 0, 0
        while i < n and j < m:
            if s[i] >= g[j]:
                j += 1
            i += 1
        return j

for循环写法:

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        if not s:
            return 0
        m, n = len(g), len(s)
        s.sort()
        g.sort()
        j = 0
        for i in range(n):
            if j < m and s[i] >= g[j]:
                j += 1
        return j
  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)

2.双指针 + 从大胃口孩子开始喂

 步骤:1.排序  2.双指针  3.循环数字比大小

不同于从小胃口孩子喂,除了倒序访问的区别外,

从大胃口孩子开始喂不能直接返回索引,因此多了一个变量ans

和从小胃口一样,写法有while循环写法和for循环写法,推荐while循环写法,可读性较强,

可以理解为for循环写法衍生于while循环写法

while循环写法:

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        if not s:
            return 0
        g.sort()
        s.sort()
        m, n = len(g), len(s)
        i, j = n - 1, m - 1
        ans = 0
        while i >= 0 and j >= 0:
            if s[i] >= g[j]:
                i -= 1
                ans += 1
            j -= 1
        return ans

for循环写法:

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        if not s:
            return 0
        g.sort()
        s.sort()
        m, n = len(g), len(s)
        i = n - 1
        ans = 0
        for j in range(m - 1, -1, -1):
            if i >= 0 and s[i] >= g[j]:
                i -= 1
                ans += 1
        return ans
  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)

3.可以用栈/队列代替双指针

实现的逻辑相同,就是用栈/队列的抛出操作代替了移动指针操作,但队列比指针操作耗时略大:

从小胃口孩子开始喂(栈):

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        if not s:
            return 0
        ans = 0
        g.sort()
        s.sort()
        while g and s:
            ch_g = g.pop()
            if s[-1] >= ch_g:
                s.pop()
                ans += 1
        return ans

从大胃口孩子开始喂(队列):

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        if not s:
            return 0
        ans = 0
        g.sort()
        s.sort()
        gdeque = deque(g)
        sdeque = deque(s)
        while gdeque and sdeque:
            ch_s = sdeque.popleft()
            if ch_s >= gdeque[0]:
                gdeque.popleft()
                ans += 1
        return ans
  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(n)

三、为什么两种实现方式遍历的数组不同

模式识别目的是快速找到一个解法,

但为了满足自己好奇心以及加快以后的模式识别,我想探究一下这个问题

配对条件是饼干大小s[j] >= 胃口g[i],即饼干大于胃口

从小到大配对时,需要遍历要求较大者饼干,保证所有大饼干配对

即从小到大遍历要求较大者(饼干),防止小饼干无法配对导致错过大饼干,

如果遍历胃口,面临饼干组左端尺寸过小的饼干时,无法继续找更大的饼干

从大到小配对时,需要遍历要求较小者胃口,保证所有小胃口配对

即从大到小遍历要求较小者(胃口),防止大胃口无法配对导致错过小胃口,

如果遍历饼干,面临胃口组右端胃口过大的孩子时,无法继续找更小的胃口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2286391.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【大模型】Ollama+AnythingLLM搭建RAG大模型私有知识库

文章目录 一、AnythingLLM简介二、搭建本地智能知识库2.1 安装Ollama2.2 安装AnythingLLM 参考资料 一、AnythingLLM简介 AnythingLLM是由Mintplex Labs Inc.开发的一个全栈应用程序&#xff0c;是一款高效、可定制、开源的企业级文档聊天机器人解决方案。AnythingLLM能够将任…

代理模式 -- 学习笔记

代理模式学习笔记 什么是代理&#xff1f; 代理是一种设计模式&#xff0c;用户可以通过代理操作&#xff0c;而真正去进行处理的是我们的目标对象&#xff0c;代理可以在方法增强&#xff08;如&#xff1a;记录日志&#xff0c;添加事务&#xff0c;监控等&#xff09; 拿一…

JVM_类的加载、链接、初始化、卸载、主动使用、被动使用

①. 说说类加载分几步&#xff1f; ①. 按照Java虚拟机规范,从class文件到加载到内存中的类,到类卸载出内存为止,它的整个生命周期包括如下7个阶段: 第一过程的加载(loading)也称为装载验证、准备、解析3个部分统称为链接(Linking)在Java中数据类型分为基本数据类型和引用数据…

ProfibusDP主机与从机交互

ProfibusDP 主机SD2索要数据下发&#xff1a;68 08 F7 68 01 02 03 21 05 06 07 08 1C 1668&#xff1a;SD2 08&#xff1a;LE F7&#xff1a;LEr 68&#xff1a;SD2 01:目的地址 02&#xff1a;源地址 03:FC_CYCLIC_DATA_EXCHANGE功能码 21&#xff1a;数据地址 05,06,07,08&a…

Java设计模式:结构型模式→组合模式

Java 组合模式详解 1. 定义 组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将对象组合成树形结构以表示“部分-整体”的层次。组合模式使得客户端能够以统一的方式对待单个对象和对象集合的一致性&#xff0c;有助于处理树形结构…

【福州市AOI小区面】shp数据学校大厦商场等占地范围面数据内容测评

AOI城区小区面样图和数据范围查看&#xff1a; — 字段里面有name字段。分类比较多tpye&#xff1a;每个值代表一个类型。比如字段type中1549代表小区住宅&#xff0c;1563代表学校。小区、学校等占地面积范围数据 —— 小区范围占地面积面数据shp格式 无偏移坐标&#xff0c;只…

【Python实现机器遗忘算法】复现2023年TNNLS期刊算法UNSIR

【Python实现机器遗忘算法】复现2023年TNNLS期刊算法UNSIR 1 算法原理 Tarun A K, Chundawat V S, Mandal M, et al. Fast yet effective machine unlearning[J]. IEEE Transactions on Neural Networks and Learning Systems, 2023. 本文提出了一种名为 UNSIR&#xff08;Un…

基于SpringBoot的阳光幼儿园管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

【开源免费】基于SpringBoot+Vue.JS景区民宿预约系统(JAVA毕业设计)

本文项目编号 T 162 &#xff0c;文末自助获取源码 \color{red}{T162&#xff0c;文末自助获取源码} T162&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

安卓逆向之脱壳-认识一下动态加载 双亲委派(一)

安卓逆向和脱壳是安全研究、漏洞挖掘、恶意软件分析等领域的重要环节。脱壳&#xff08;unpacking&#xff09;指的是去除应用程序中加固或保护措施的过程&#xff0c;使得可以访问应用程序的原始代码或者数据。脱壳的重要性&#xff1a; 分析恶意软件&#xff1a;很多恶意软件…

马尔科夫模型和隐马尔科夫模型区别

我用一个天气预报和海藻湿度观测的比喻来解释&#xff0c;保证你秒懂&#xff01; 1. 马尔可夫模型&#xff08;Markov Model, MM&#xff09; 特点&#xff1a;状态直接可见 场景&#xff1a;天气预报&#xff08;晴天→雨天→阴天…&#xff09;核心假设&#xff1a; 下一个…

Python NumPy(7):连接数组、分割数组、数组元素的添加与删除

1 连接数组 函数描述concatenate连接沿现有轴的数组序列stack沿着新的轴加入一系列数组。hstack水平堆叠序列中的数组&#xff08;列方向&#xff09;vstack竖直堆叠序列中的数组&#xff08;行方向&#xff09; 1.1 numpy.concatenate numpy.concatenate 函数用于沿指定轴连…

【LLM】deepseek多模态之Janus-Pro和JanusFlow框架

note 文章目录 note一、Janus-Pro&#xff1a;解耦视觉编码&#xff0c;实现多模态高效统一技术亮点模型细节 二、JanusFlow&#xff1a;融合生成流与语言模型&#xff0c;重新定义多模态技术亮点模型细节 Reference 一、Janus-Pro&#xff1a;解耦视觉编码&#xff0c;实现多模…

2000-2021年 全国各地级市专利申请与获得情况、绿色专利申请与获得情况数据

2000-2021年 全国各地级市专利申请与获得情况、绿色专利申请与获得情况数据.ziphttps://download.csdn.net/download/2401_84585615/89575931 https://download.csdn.net/download/2401_84585615/89575931 2000至2021年&#xff0c;全国各地级市的专利申请与获得情况呈现出显著…

51单片机(STC89C52)开发:点亮一个小灯

软件安装&#xff1a; 安装开发板CH340驱动。 安装KEILC51开发软件&#xff1a;C51V901.exe。 下载软件&#xff1a;PZ-ISP.exe 创建项目&#xff1a; 新建main.c 将main.c加入至项目中&#xff1a; main.c:点亮一个小灯 #include "reg52.h"sbit LED1P2^0; //P2的…

240. 搜索二维矩阵||

参考题解&#xff1a;https://leetcode.cn/problems/search-a-2d-matrix-ii/solutions/2361487/240-sou-suo-er-wei-ju-zhen-iitan-xin-qin-7mtf 将矩阵旋转45度&#xff0c;可以看作一个二叉搜索树。 假设以左下角元素为根结点&#xff0c; 当target比root大的时候&#xff…

反向代理模块b

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当于…

【Linux权限】—— 于虚拟殿堂,轻拨密钥启华章

欢迎来到ZyyOvO的博客✨&#xff0c;一个关于探索技术的角落&#xff0c;记录学习的点滴&#x1f4d6;&#xff0c;分享实用的技巧&#x1f6e0;️&#xff0c;偶尔还有一些奇思妙想&#x1f4a1; 本文由ZyyOvO原创✍️&#xff0c;感谢支持❤️&#xff01;请尊重原创&#x1…

EasyExcel使用详解

文章目录 EasyExcel使用详解一、引言二、环境准备与基础配置1、添加依赖2、定义实体类 三、Excel 读取详解1、基础读取2、自定义监听器3、多 Sheet 处理 四、Excel 写入详解1、基础写入2、动态列与复杂表头3、样式与模板填充 五、总结 EasyExcel使用详解 一、引言 EasyExcel 是…

前端-Rollup

Rollup 是一个用于 JavaScript 的模块打包工具&#xff0c;它将小的代码片段编译成更大、更复杂的代码&#xff0c;例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式&#xff0c;而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由…