news 2026/6/9 20:55:24

贪心算法专题(一):局部最优的魔力——“抠门”的「分发饼干」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
贪心算法专题(一):局部最优的魔力——“抠门”的「分发饼干」

哈喽各位,我是前端小L。

欢迎来到贪心算法专题第一篇! 贪心算法没有固定的套路模板(不像回溯有backtrack模板,DP 有dp数组)。贪心的核心在于策略

我们通过“分发饼干”这道题来感受一下:假设你是一位精打细算的家长,手里有一堆大小不一的饼干,面前站着一堆胃口大小不一的孩子。你的目标是喂饱尽可能多的孩子,但为了不浪费,你应该怎么分?

力扣 455. 分发饼干

https://leetcode.cn/problems/assign-cookies/

题目分析:

  • 输入

    • g(greed factor):数组,表示每个孩子的胃口值(最小能吃饱的量)。

    • s(size):数组,表示每块饼干的大小。

  • 规则:如果s[j] >= g[i],我们可以把饼干j给孩子i,这个孩子就满足了。

  • 目标:尽可能满足更多的孩子。

核心思维:大饼干喂大胃口,还是小饼干喂小胃口?

如果我们随便分:

  • 拿一块超级大的饼干,喂给一个胃口很小的孩子 ->浪费(大饼干本可以喂给大胃口的孩子)。

  • 拿一块很小的饼干,喂给一个胃口很大的孩子 ->无效(孩子吃不饱,饼干也没了)。

贪心策略一(小喂小):优先用最小的饼干,去喂胃口最小的孩子。

  • 如果这块最小的饼干能满足他,那就给他(局部最优:既喂饱了一个,又保留了较大的饼干给后面)。

  • 如果这块饼干连最小胃口都满足不了,那这块饼干就是废的,谁也喂不饱,丢掉(也就是换下一块大一点的)。

贪心策略二(大喂大):优先用最大的饼干,去喂胃口最大的孩子。

  • 如果最大的饼干能满足最大的胃口,那就给他。

  • 如果满足不了,说明这个大胃口的孩子谁也救不了,放弃他,看下一个胃口稍微小一点的孩子。

这两种策略都是对的!为了便于实现,我们通常选择**“先排序,再匹配”**。

算法流程 (策略一:小饼干先喂小胃口)

  1. 排序:将孩子的胃口g和饼干大小s都从小到大排序。

  2. 双指针遍历

    • child指向第 0 个孩子。

    • cookie指向第 0 块饼干。

  3. 循环判断

    • 如果s[cookie] >= g[child]

      • 太好了,这块饼干正好(或勉强)能喂饱这个孩子。

      • child++(换下一个孩子)。

      • cookie++(换下一块饼干)。

    • 如果s[cookie] < g[child]

      • 这块饼干太小了,连胃口最小的孩子都满足不了。

      • cookie++(换一块更大的试试,孩子原地不动)。

  4. 结束child的数值就是被满足的孩子总数。

代码实现 (C++)

C++

#include <vector> #include <algorithm> using namespace std; class Solution { public: int findContentChildren(vector<int>& g, vector<int>& s) { // 1. 贪心的前提通常是“有序” sort(g.begin(), g.end()); sort(s.begin(), s.end()); int child = 0; int cookie = 0; // 2. 遍历饼干和孩子 while (child < g.size() && cookie < s.size()) { // 如果当前的饼干能满足当前的孩子 if (s[cookie] >= g[child]) { child++; // 孩子吃饱了,换下一个 } // 无论能不能满足,这块饼干都“消耗”了 // (如果满足了,被吃了;如果不满足,它太小了没用,被跳过) cookie++; } return child; } };

深度复杂度分析

  • 时间复杂度:O(N log N + M log M)

    • 瓶颈在于排序gs的排序分别需要N log NM log M

    • 后面的双指针遍历只需要O(N + M)

  • 空间复杂度:O(1)(或 O(log N) 取决于排序算法的实现)

    • 我们只需要几个变量,不需要额外的数组空间。

总结:贪心的第一准则

今天这道题虽然简单,但它揭示了贪心算法最重要的两个特征:

  1. 排序:大多数贪心问题,都需要在有序的数据上才能进行“最优选择”。如果题目没给有序数组,你往往需要先sort

  2. 局部最优 -> 全局最优

    • 局部最优:这块饼干哪怕只比孩子的胃口大一点点,我也给它用了,绝不浪费更大的饼干。

    • 全局最优:最后喂饱的孩子最多。

这种**“没有后效性”**(现在的选择不会影响未来的可行性,只会让未来更好做)是贪心算法生效的基础。

下一题预告: 如果情况稍微复杂一点,我们面对的不是静态的饼干,而是一个波动的序列。我们要在一个忽高忽低的序列中,统计“峰值”和“谷值”的变化次数(摆动序列)。这道题将展示如何通过**忽略“平坡”**这一局部贪心策略来解决问题。

下期见!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 8:16:39

基于Java + vue宠物医院管理系统(源码+数据库+文档)

宠物医院管理 目录 基于springboot vue宠物医院系统 一、前言 二、系统功能演示 详细视频演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于springboot vue宠物医院系统 一、前言 博主介绍…

作者头像 李华
网站建设 2026/6/10 4:45:40

基于Java+ vue酒店管理系统(源码+数据库+文档)

酒店管理 目录 基于springboot vue酒店管理系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于springboot vue酒店管理系统 一、前言 博主介绍&#xff1a;✌️大…

作者头像 李华
网站建设 2026/6/5 3:24:24

sdl安装测试-mingw32环境

安装sdl 下载 SDL3-devel-3.2.28-mingw.zip 并解压到 D:\soft\vcpkg\myCMakeLists.txt cmake_minimum_required(VERSION 3.15) project(SDL3Demo LANGUAGES C CXX) # 强制 32-bit 编译 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") set(CMAKE_CXX_FLAGS "${…

作者头像 李华
网站建设 2026/6/10 12:59:01

深入了解HTTP缓存!测试要注意这5大应用场景

如果我们测试一个版本时遇到Bug&#xff0c;然后等开发改了以后及时验证&#xff0c;开发可能会好心提醒一句&#xff0c;你先清一下浏览器缓存再测&#xff0c;是不是经常碰到这种情况&#xff1f; 所以我们在测试中要经常和缓存打交道&#xff0c;既然是老朋友了&#xff0c…

作者头像 李华
网站建设 2026/6/10 2:48:48

Uni-Med: A Unified Medical Generalist Foundation Model For Multi-Task Learning Via Connector-MoE

1. 研究背景和意义 随着多模态大语言模型(MLLMs)的发展,构建一个统一的、通用的医学基础模型已成为趋势。这种模型旨在通过单一架构和共享参数处理多种医学任务(如问答、报告生成、分类等),从而摆脱传统“一任务一模型”的繁琐开发模式。然而,在医学领域,由于任务和模…

作者头像 李华
网站建设 2026/6/10 9:54:53

如何解决7个OpenMower智能割草机器人常见问题:从入门到精通

如何解决7个OpenMower智能割草机器人常见问题&#xff1a;从入门到精通 【免费下载链接】OpenMower Lets upgrade cheap off-the-shelf robotic mowers to modern, smart RTK GPS based lawn mowing robots! 项目地址: https://gitcode.com/GitHub_Trending/op/OpenMower …

作者头像 李华