【四】【算法分析与设计】贪心算法的初见

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 * 10(4)

  • 0 <= s.length <= 3 * 10(4)

  • 1 <= g[i], s[j] <= 2(31) - 1

 
class Solution {
public:int findContentChildren(vector<int>& children, vector<int>& cookies) {sort(children.begin(), children.end());sort(cookies.begin(), cookies.end());int child = 0, cookie = 0;while (child < children.size() && cookie < cookies.size()) {if (children[child] <= cookies[cookie])++child;++cookie;}return child;}
};

问题的核心是尽可能满足更多孩子的胃口,每个孩子最多能得到一块饼干,每块饼干也只能分给一个孩子,给定一个孩子数组children代表每个孩子的胃口值,一个饼干数组cookies代表每块饼干的大小,求最多有多少孩子能得到饼干满足胃口。

sort(children.begin(), children.end());这行代码将children数组按胃口值从小到大排序。

sort(cookies.begin(), cookies.end());这行代码将cookies数组按饼干大小从小到大排序。

int child = 0, cookie = 0;初始化两个变量childcookie,分别表示当前考虑到的孩子和饼干的索引。

while (child < children.size() && cookie < cookies.size()) {这个循环继续执行直到所有孩子都被考虑过或所有饼干都被尝试分配。

if (children[child] <= cookies[cookie]) ++child;如果当前饼干的大小能满足当前孩子的胃口,那么这个孩子被满足,移动到下一个孩子。

++cookie;无论当前的饼干是否能满足当前的孩子,都将考虑下一块饼干。

时间复杂度和空间复杂度

时间复杂度:O(nlogn)。主要时间开销来自于排序childrencookies数组,假设childrencookies的长度分别为m和n,那么时间复杂度为O(mlogm + nlogn)。遍历数组的过程时间复杂度为O(m+n),所以总体时间复杂度为O(nlogn),这里n是两个数组中较长的那个的长度。

空间复杂度:O(1)。除了输入的数组外,我们只使用了常数空间。

135. 分发糖果

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

  • 每个孩子至少分配到 1 个糖果。

  • 相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目

示例 1:

输入:ratings = [1,0,2] 输出:5 解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。

示例 2:

输入:ratings = [1,2,2] 输出:4 解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。 第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。

提示:

  • n == ratings.length

  • 1 <= n <= 2 * 10(4)

  • 0 <= ratings[i] <= 2 * 10(4)

 
class Solution {
public:int candy(vector<int>& ratings) {int size = ratings.size();if (size < 2) {return size;}vector<int> num(size, 1);for (int i = 1; i < size; ++i) {if (ratings[i] > ratings[i - 1]) {num[i] = num[i - 1] + 1;}}for (int i = size - 1; i > 0; --i) {if (ratings[i] < ratings[i - 1]) {num[i - 1] = max(num[i - 1], num[i] + 1);}}return accumulate(num.begin(), num.end(),0); // std::accumulate 可以很方便地求和}
};

定义变量 size 为评分数组 ratings 的长度。

如果 size 小于 2,直接返回 size。因为如果只有一个孩子,那他就是唯一的获得糖果的人,直接返回1;如果没有孩子,返回0。

初始化一个大小与 ratings 相同,值全为1的数组 num。这一步确保了每个孩子至少得到一颗糖果。

第一次遍历:从左到右遍历 ratings

如果当前孩子(i对应孩子)的评分高于左边的孩子(ratings[i] > ratings[i - 1]),则当前孩子得到的糖果数应该比左边的孩子多一颗(num[i] = num[i - 1] + 1)。

第二次遍历:从右到左遍历 ratings

如果当前孩子(i-1对应孩子)的评分高于右边的孩子(ratings[i] < ratings[i - 1]),则左边的孩子得到的糖果数应该是其原本的数目和右边孩子的糖果数加一中的较大值(num[i - 1] = max(num[i - 1], num[i] + 1))。

最后,使用 accumulate 函数对 num 数组进行求和,得到总共需要的糖果数,并返回这个值。accumulate 函数起始值为0,意味着从0开始累加 num 数组中所有元素的值。

accumulate函数

accumulate 函数是 C++ 标准库中 <numeric> 头文件提供的一个非常实用的数值累加函数。它用于计算一个给定范围内所有元素的累加和,或者在提供了自定义操作时,按照该操作进行累加。accumulate 的基本用法是计算序列的总和,但通过自定义加法操作,它也可以用于更复杂的累加操作,如累乘。

基本用法

基础版本的 accumulate 接受三个参数:序列的开始迭代器、结束迭代器和累加的初始值。如果不指定操作,则默认进行加法操作。下面是一个简单的例子:

 
#include <numeric> // 引入accumulate的头文件
#include <vector>std::vector<int> v = {1, 2, 3, 4, 5};
int sum = std::accumulate(v.begin(), v.end(), 0); // 计算总和

在这个例子中,accumulate0 开始,将 v 中的每个元素相加,计算出总和为 15

使用自定义操作

accumulate 还允许你指定一个自定义的二元操作函数,来代替默认的加法操作。这个二元操作接受两个参数:累加值(到当前为止的结果)和序列中的当前元素。这使得 accumulate 变得非常灵活,可以实现各种复杂的累加逻辑。

例如,使用 accumulate 来计算一个数列的乘积:

 
#include <numeric>
#include <vector>std::vector<int> v = {1, 2, 3, 4, 5};
int product = std::accumulate(v.begin(), v.end(), 1, [](int a, int b) {return a * b;
});

这里,初始值设为 1(乘法的单位元),并通过一个 lambda 表达式指定乘法为累加操作。最终,product 的值为 120,即 1*2*3*4*5 的结果。

注意事项

accumulate 默认使用加法操作时,累加初始值的类型决定了整个操作的类型。例如,如果初始值为整数,那么即使数组是浮点数,累加结果也会被截断为整数。因此,选择合适的初始值类型是非常重要的。

435. 无重叠区间

给定一个区间的集合 intervals ,其中 intervals[i] = [start(i), end(i)] 。返回 需要移除区间的最小数量,使剩余区间互不重叠

示例 1:

输入: intervals = [[1,2],[2,3],[3,4],[1,3]] 输出: 1 解释: 移除 [1,3] 后,剩下的区间没有重叠。

示例 2:

输入: intervals = [ [1,2], [1,2], [1,2] ] 输出: 2 解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。

示例 3:

输入: intervals = [ [1,2], [2,3] ] 输出: 0 解释: 你不需要移除任何区间,因为它们已经是无重叠的了。

提示:

  • 1 <= intervals.length <= 10(5)

  • intervals[i].length == 2

  • -5 * 10(4) <= start(i) < end(i) <= 5 * 10(4)

 
int eraseOverlapIntervals(vector<vector<int>>& intervals) {if (intervals.empty()) {return 0;}int n = intervals.size();sort(intervals.begin(), intervals.end(), [](vector<int> a, vector<int> b) {return a[1] < b[1];});int total = 0, prev = intervals[0][1];for (int i = 1; i < n; ++i) {if (intervals[i][0] < prev) {++total;} else {prev = intervals[i][1];}}return total;}

检查区间数组是否为空

if (intervals.empty()) { return 0; }如果区间数组为空,则没有需要移除的区间,直接返回0。

获取区间数组的大小

int n = intervals.size();这里定义了一个变量 n 来存储区间数组的长度。

按区间结束时间排序

sort(intervals.begin(), intervals.end(), [](vector<int> a, vector<int> b) { return a[1] < b[1]; });使用标准库函数 sort,通过自定义的比较函数,将区间按照结束时间升序排序。这样做的目的是尽可能让区间不重叠,因为结束得早的区间留给后面的区间的空间就越多。

初始化计数器和前一个区间的结束右端点

int total = 0, prev = intervals[0][1];初始化需要移除的区间数量 total 为0,并将 prev 设置为第一个区间的结束时间。prev 用于记录当前不重叠区间的最后一个区间的结束时间。

遍历区间数组,确定需要移除的区间数量

for (int i = 1; i < n; ++i) { if (intervals[i][0] < prev) { ++total; } else { prev = intervals[i][1]; } }从第二个区间开始遍历,如果当前区间的开始时间小于前一个区间的结束时间 prev,说明这两个区间重叠,需要移除一个区间,因此 total 自增1。如果不重叠,更新 prev 为当前区间的结束时间,继续向后比较。

标准库函数sort

C++ 标准库中的 sort 函数是一个非常强大且灵活的排序算法,主要用于对数组或容器内的元素进行排序。它位于 <algorithm> 头文件中。sort 函数可以对一个序列进行默认的升序排序,也可以通过自定义比较函数来指定排序规则。

基本用法

默认情况下,sort 对序列进行升序排序。如果你想对一个数组或者 vector 排序,可以这样使用:

 
#include <algorithm> // 引入算法库
#include <vector>std::vector<int> v = {4, 2, 5, 3, 1};
std::sort(v.begin(), v.end());

在上述代码中,v.begin()v.end() 分别是容器 v 的起始迭代器和终止迭代器,sort 函数会将 v 中的元素从小到大排序。

自定义比较函数

sort 函数允许你通过自定义比较函数来指定排序规则,这让你能够实现复杂的排序逻辑,比如降序排序或者根据对象的某个属性排序。

自定义比较函数可以是一个普通函数,也可以是一个lambda表达式。比较函数需要接受两个参数(被比较的元素),并返回一个布尔值,指示第一个参数是否应该位于第二个参数之前。

使用普通函数作为比较函数

 
bool compare(int a, int b) {return a > b; // 降序排序
}std::vector<int> v = {4, 2, 5, 3, 1};
std::sort(v.begin(), v.end(), compare);

使用 Lambda 表达式

Lambda 表达式提供了一种便捷的方式来定义临时的比较函数,这在实现简单的自定义排序规则时非常有用:

 
std::vector<int> v = {4, 2, 5, 3, 1};
std::sort(v.begin(), v.end(), [](int a, int b) {return a > b; // 降序排序
});

对象排序

如果你想根据对象的某个属性排序,可以这样做:

 
struct Person {std::string name;int age;
};bool compareByAge(const Person& a, const Person& b) {return a.age < b.age; // 按年龄升序排序
}std::vector<Person> people = {{"Alice", 30}, {"Bob", 25}, {"Carol", 20}};
std::sort(people.begin(), people.end(), compareByAge);

或者使用 Lambda 表达式:

 
std::sort(people.begin(), people.end(), [](const Person& a, const Person& b) {return a.age < b.age; // 按年龄升序排序
});

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

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

相关文章

AI时代Python金融大数据分析实战:ChatGPT让金融大数据分析插上翅膀【文末送书-38】

文章目录 Python驱动的金融智能&#xff1a;数据分析、交易策略与风险管理Python在金融数据分析中的应用 实战案例&#xff1a;基于ChatGPT的金融事件预测AI时代Python金融大数据分析实战&#xff1a;ChatGPT让金融大数据分析插上翅膀【文末送书-38】 Python驱动的金融智能&…

eVTOL适航领先新构型,沃飞长空布局空中交通新局面

汽车、火车、飞机……人类对于出行方式的探索从未停止。随着沃飞长空旗下首款自研eVTOL(飞行汽车)AE200适航技术验证机一阶段顺利试飞,eVTOL(飞行汽车)这种面向空中交通的新型交通工具进入了我们的视野,那么eVTOL(飞行汽车)是什么?eVTOL(飞行汽车)前景怎么样? eVTOL(飞行汽车…

Power Apps 学习笔记 -- Action

文章目录 1. Action 简介2. Action 配置3. 待补充 1. Action 简介 Action基础教程 : Action概述 操作Action: 1. 操作Action类似于工作流Workflow&#xff0c;提供一些重用性的操作&#xff0c;允许工作流或其他Web服务端点调用(例如javascript). 2. Action 类似于c#当中的一个…

专题二 -滑动窗口 - leetcode 209. 长度最小的子数组 | 中等难度

leetcode 209. 长度最小的子数组 leetcode 209. 长度最小的子数组 | 中等难度1. 题目详情1. 原题链接2. 基础框架 2. 解题思路1. 题目分析2. 算法原理3. 时间复杂度 3. 代码实现4. 知识与收获 leetcode 209. 长度最小的子数组 | 中等难度 1. 题目详情 给定一个含有 n 个正整数…

Android14音频进阶:AudioTrack如何巧妙衔接AudioFlinger(五十七)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

人工智能迷惑行为大赏!

目录 人工智能迷惑行为大赏 一&#xff1a;人工智能的“幽默”瞬间 1. 图像识别出现AI的极限 2. 小批量梯度下降优化器 3. 智能聊天机器人的冰雹问题 4. 大语言模型-3经典语录 二&#xff1a;技术原理探究 1. 深度学习 2. 机器学习 3. 自然语言处理 4. 计算机视觉 三…

博士推荐 | 拥有10多年纺织工程经验,纤维与聚合物科学博士

编辑 / 木子 审核 / 朝阳 伟骅英才 伟骅英才致力于以大数据、区块链、AI人工智能等前沿技术打造开放的人力资本生态&#xff0c;用科技解决职业领域问题&#xff0c;提升行业数字化服务水平&#xff0c;提供创新型的产业与人才一体化服务的人力资源解决方案和示范平台&#x…

什么是架构?架构设计原则是哪些?什么是设计模式?设计模式有哪些?

什么是架构?架构设计原则是哪些?什么是设计模式?设计模式有哪些? 架构的本质 架构本身是一种抽象的、来自建筑学的体系结构,其在企业及IT系统中被广泛应用。 架构的本质是对事物复杂性的管理,是对一个企业、一个公司、一个系统复杂的内部关系进行结构化、体系化的抽象,…

骨传导游泳耳机哪个牌子好?四款实力扛鼎的游泳耳机推荐

游泳是一项全身性的运动&#xff0c;能够有效锻炼身体、释放压力。然而&#xff0c;在水下欣赏音乐却成为了一项难题。普通的耳机在水中无法使用&#xff0c;而骨传导技术的出现&#xff0c;让游泳与音乐完美结合。今天&#xff0c;我们将为大家推荐四款超强的的骨传导游泳耳机…

分享一个国内可用的AIGC网站,PC/手机端通用|免费无限制,支持Claude3 Claude2

背景 AIGC作为一种基于人工智能技术的自然语言处理工具&#xff0c;近期的热度直接沸腾&#x1f30b;。 作为一个AI爱好者&#xff0c;翻遍了各大基于AIGC的网站&#xff0c;终于找到一个免费&#xff01;免登陆&#xff01;手机电脑通用&#xff01;国内可直接对话的AIGC&am…

EasyRecovery恢复电脑丢失数据怎么样?

电脑是我们大家熟悉并且常用的数据存储设备&#xff0c;也是综合性非常强的数据处理设备。对于电脑设备来讲&#xff0c;最主要的数据存储介质是硬盘&#xff0c;电脑硬盘被划分成多个分区&#xff0c;在电脑上表现为C盘&#xff0c;E盘等&#xff0c;用来保存系统文件以及其他…

记OnlyOffice的两个大坑

开发版&#xff0c;容器部署&#xff0c;试用许可已安装。 word&#xff0c;ppt&#xff0c;excel均能正常浏览。 自带的下载菜单按钮能用。 但config里自定义的downloadAs方法却不一而足。 word能正常下载&#xff0c;excel和ppt都不行。 仔细比对调试了代码。发现app.js…

yolov5-v6.0详细解读

yolov5-v6.0详细解读 一、yolov5版本介绍二、网络结构2.1 Backbone特征提取部分2.1.1 ConvBNSiLU模块2.1.2 C3模块2.1.2.1 BottleNeck模块 2.1.3 SPPF模块 2.2 Neck特征融合部分2.2.1 FPN2.2.2 PANet 2.3Head模块 三、目标框回归3.1 yolo标注格式3.2 yolov4目标回归框3.3 yolov…

《行业指标体系白皮书》重磅发布,剖析指标建设困境,构建前瞻性的指标体系(附下载)

正处于企业指标建设过程中的你&#xff0c;是否经常遇到这样的问题&#xff1a; • 各个部门独立建设信息系统&#xff0c;由此产生的指标定义和计算方式各异&#xff0c;导致管理层无法快速准确地掌握整体业务运行状况 • 缺乏对指标的统一管理和规范&#xff0c;产生重复的指…

IO复用之select

目录 一.select方法介绍 2.1 select 系统调用的原型 2.2 集合的数据结构 2.2.1 fd_set 结构如下: 2.2.2 关于集合fd_set的解析 2.3 select第一个参数 2.4 select方法之超时时间timeout 2.5 select方法的用法简述及返回值 2.6 如何检测集合中有哪些描述符有事件就绪 三…

【建议收藏】大气颗粒物与VOCs PMF源解析

查看原文>>>最新大气颗粒物与VOCs PMF源解析实践技术应用 目前&#xff0c;大气颗粒物和臭氧污染成为我国亟待解决的环境问题。颗粒物和臭氧污染不仅对气候和环境有重要影响&#xff0c;而且对人体健康有严重损害。而臭氧的前体物之一为挥发性有机物&#xff08;VOCs&…

Orange3数据预处理(离散化组件)

离散化&#xff1a;将数值属性转换为分类属性。 输出 数据&#xff1a;具有离散化值的数据集 设置离散化的默认方法。 选择变量以为每个变量设置特定的离散化方法。将鼠标悬停在变量上显示区间。 离散化方法Keep numeric(保持数值)&#xff1a;保持变量不变。Remove (移除)&a…

罐头鱼AI短视频矩阵获客|AI视频批量生成

罐头鱼AI传单功能操作说明&#xff0c;智能化提升您的视频营销效率&#xff01; 在这个信息爆炸的时代&#xff0c;短视频已成为企业营销的重要方式之一。而为了更高效地进行视频营销&#xff0c;罐头鱼AI传单功能应运而生&#xff0c;为您提供全方位的视频管理和发布服务。 首…

【最全最详细】微信第三方平台开发 —— 接收公众号事件/消息

文章目录 1. 整体流程2. 成为服务商2.1. 首先打开微信开放平台&#xff0c;注册并登录你的账号2.2. 进行开发者资质认证2.3. 创建第三方平台并提交审核 3. 搭建第三方平台后端服务3.1. 管理员设置 和 权限集设置3.2. 开发资料设置3.3. 进行商家授权操作3.3.0. 加密解密操作3.3.…

新零售SaaS架构:什么是线上商城系统?

零售商家为什么要建设线上商城 传统的实体门店服务范围有限&#xff0c;只能吸引周边500米内的消费者。因此&#xff0c;如何拓展服务范围&#xff0c;吸引更多消费者到店&#xff0c;成为了店家迫切需要解决的问题。 缺乏忠实顾客&#xff0c;客户基础不稳&#xff0c;往往是…