【LeetCode贪心#07】分糖果(两个维度)
发糖果
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
你需要按照以下要求,帮助老师给这些孩子分发糖果:
- 每个孩子至少分配到 1 个糖果。
- 相邻的孩子中,评分高的孩子必须获得更多的糖果。
那么这样下来,老师至少需要准备多少颗糖果呢?
示例 1:
- 输入: [1,0,2]
- 输出: 5
- 解释: 你可以分别给这三个孩子分发 2、1、2 颗糖果。
示例 2:
- 输入: [1,2,2]
- 输出: 4
- 解释: 你可以分别给这三个孩子分发 1、2、1 颗糖果。第三个孩子只得到 1 颗糖果,这已满足上述两个条件。
思路
根据示例1、2来看,我们只需要对满足规则的两种情况发放糖果即可,目标是在满足规则的前提下消耗最少的糖果(因此发的糖果数量有可能是不公平的)
怎么做呢?其实也简单,就是遍历数组,比较前后元素的大小关系,由此分配糖果即可
但是细想一下,遍历过程也是有坑的
举个例子:

从左往右遍历ratings数组,得到每个小孩应该分配的糖果数【左边孩子与右边孩子相比得出的结果】
此时的贪心:
局部最优:只要右边评分比左边大(ratings[i] > ratings[i - 1]),右边的孩子就多一个糖果
全局最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果
//从左往右遍历ratings数组,左边孩子与右边孩子相比
for(int i = 1; i < ratings.size(); ++i){//从下标1开始
if((ratings[i] > ratings[i - 1]) candyCount[i] = candyCount[i - 1] + 1;
}
但是,下标4和5位置,下标5的评分比4低,但是获得的糖果数一样,这不满足规则
所以还要从右往左遍历一遍【右边孩子与左边孩子相比得出的结果】,综合之后取最大值得出要分配的糖果数

此时的贪心:
局部最优:只要左边评分比右边大(ratings[i] > ratings[i + 1]),左边的孩子就多一个糖果
全局最优:相邻的孩子中,评分高的左孩子获得比右边孩子更多的糖果
//从右往左遍历ratings数组,右边孩子与左边孩子相比
for(int i = ratings.size() - 2; i >= 0; --i){//从倒数第二个下标开始
if(ratings[i] > ratings[i + 1]){
candyCount[i] = max(candyCount[i + 1] + 1, candyCount[i]);//取当前糖果数与之前的最大值
}
}
在第二个循环中,当当前孩子的评分高于右边孩子时,当前孩子需要得到的糖果数应该是右边孩子已经获得的糖果数加上一颗糖果。但是由于在从左到右第一次遍历中已经分配了一部分糖果,所以当前孩子最少也会拿到和左边孩子一样多的糖果数,因此需要取 candyCount[i + 1] + 1 和 candyCount[i] 中的较大值作为当前孩子最终得到的糖果数。其中 candyCount[i + 1] + 1 表示右边孩子已经获得的糖果数加上一颗糖果, candyCount[i] 表示当前孩子之前分配的糖果数,也就是至少能够得到的糖果数。这样可以保证分配的糖果数满足题目要求,并且不浪费糖果数量。
注意:将右边孩子和左边孩子相比时,必须从右往左遍历,不能从左往右然后通过改下标的方式来比较
代码
本题仍然采用了两次贪心策略
- 一次是从左到右遍历,只比较右边孩子评分比左边大的情况。
- 一次是从右到左遍历,只比较左边孩子评分比右边大的情况。
两次贪心最终可以得到满足规则的糖果分配数
步骤如下:
1、创建糖果数统计数组
2、从左往右遍历ratings数组,左边孩子与右边孩子相比
3、从右往左遍历ratings数组,右边孩子与左边孩子相比
4、统计糖果数
class Solution {
public:
int candy(vector<int>& ratings) {
//定义糖果统计数组
vector<int> candyCount(ratings.size(), 1);//默认给一个糖
//从左往右遍历ratings数组,左边孩子与右边孩子相比
for(int i = 1; i < ratings.size(); ++i){//从下标1开始
if(ratings[i] > ratings[i - 1]) candyCount[i] = candyCount[i - 1] + 1;
}
//从右往左遍历ratings数组,右边孩子与左边孩子相比
for(int i = ratings.size() - 2; i >= 0; --i){//从倒数第二个下标开始
if(ratings[i] > ratings[i + 1]){
candyCount[i] = max(candyCount[i + 1] + 1, candyCount[i]);
}
}
//统计糖果数
int res = 0;
for(int c : candyCount) res += c;
return res;
}
};
在第二个for循环中,遍历的是从右到左的顺序,所以需要从数组的最后一个元素的前一个元素开始,即从 ratings.size() - 2 的位置开始遍历。如果从最后一个元素开始遍历,那么就只能判断这个元素和它左边的元素之间的大小关系,而无法判断它和右边元素之间的大小关系,因为右边已经没有元素了。
【LeetCode贪心#07】分糖果(两个维度)的更多相关文章
- [LeetCode] Distribute Candies 分糖果
Given an integer array with even length, where different numbers in this array represent different k ...
- LeetCode之小孩分糖果
给定一群站好队的小孩而且按某项分值排名(姑且如果为年龄吧),年龄大的要比他身边年龄小的拿的糖要多.求怎么分配糖果使得分配的糖果数最少. 用一个数组从左到右再从右到左的遍历,向前遍历时若右边的比左边的大 ...
- [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现
[LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现 原题: There are N children standing in a line. ...
- LeetCode 1103. Distribute Candies to People (分糖果 II)
题目标签:Math 题目让我们分发糖果,分的糖果从1 开始依次增加,直到分完. for loop可以计数糖果的数量,直到糖果发完.但是还是要遍历array 给people 发糖,这里要用到 index ...
- Java实现 LeetCode 575 分糖果(看看是你的长度小还是我的种类少)
575. 分糖果 给定一个偶数长度的数组,其中不同的数字代表着不同种类的糖果,每一个数字代表一个糖果.你需要把这些糖果平均分给一个弟弟和一个妹妹.返回妹妹可以获得的最大糖果的种类数. 示例 1: 输入 ...
- CSDN 分糖果算法的思路和求助
昨天晚上 在csdn上做了一道分糖果的题目,我自个测的是没有问题,但是提交答案后,老失败,提示 你的程序正常运行并输出了结果,但是答案错误你的程序输出结果与测试数据中的输出结果不符 我先把自个思路说一 ...
- hunnu11543:小明的烦恼——分糖果
Problem description 小明在班里一直是个非常公正的孩子.这点同学和老师都非常清楚,这不,老师每周都会从家里带来一些糖果.然后叫小明把糖果分给其它小朋友,但这个班里的同学都有一个非 ...
- 牛客 2018NOIP 模你赛2 T2 分糖果 解题报告
分糖果 链接:https://www.nowcoder.com/acm/contest/173/B 来源:牛客网 题目描述 \(N\) 个小朋友围成一圈,你有无穷个糖果,想把其中一些分给他们. 从某个 ...
- 51nod——1402最大值、2479小b分糖果 (套路)
1402最大值:正向从1到n,如果没有限制,就依次递增1,如果有限制,就取那个限制和递增到这的最小值.这样保证1和每个限制点后面都是符合题意的递增,但是限制点前面这个位置可能会有落差(之前递增多了). ...
- Leetcode(4)寻找两个有序数组的中位数
Leetcode(4)寻找两个有序数组的中位数 [题目表述]: 给定两个大小为 m 和 n 的有序数组 nums1 和* nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O( ...
随机推荐
- unzip 解压缩存在Bug-- 这个方法不行啊
linux中解压大于4G的zip压缩包(已解决) tar -zxvf 压缩包名.zip
- CentOS7上面一键部署rabbitmq的简单方法
1. rabbitmq的安装部署比redis之类的要麻烦一些. 主要是他是基于erlang写的 而不是基于c或者是c++写的 2. 很多时候编译需要添加很多组件, 但是一些机器可能不会让添加这么多的组 ...
- requests模块安装
使用python写接口,必不可少的就是requests,所以事先要在python中安装requests 一.使用pip install安装(项目的命令行终端使用) 1.配置下载源地址路径(清 ...
- 【发现一个问题】macos m2 下无法使用 x86_64-linux-musl-gcc 链接含有 avx512 指令的 c 代码
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 一开始是使用 golang 中的 cgo 来编译: env ...
- (数据科学学习手札122)Python+Dash快速web应用开发——内网穿透篇
由我开源的先进Dash组件库feffery-antd-components正处于早期测试版本阶段,欢迎前往官网http://fac.feffery.tech/了解更多 1 简介 这是我的系列教程Pyt ...
- .net5发布到Linux指南
目录 Aspnetcore api 服务发布指南 一. 搭建nginx服务器 下载安装gcc编译库 下载安装pcre正则表达式库 下载安装openssl安全加密库 下载安装zlib解压库 下载解压并编 ...
- C/C++ 通过Socket 传输结构体
本质上socket无法传输结构体,我们只有将结构体装换为字节数组,或者是字符串格式来传输,到了服务端在强制类型转换一下即可,下面的代码分别提供原生写法与通过boost的实现两种,直接改改,可用于收集目 ...
- 遥感图像处理笔记之【Deep learning for Geospatial data applications — Multi-label Classification】
遥感图像处理学习(2) 前言 遥感图像处理方向的学习者可以参考或者复刻 本文初编辑于2023年12月14日 2024年1月24日搬运至本人博客园平台 文章标题:Deep learning for Ge ...
- 【排序】什么都能排的C语言qsort排序详解【超详细的宝藏级别教程】深度理解qsort排序
[排序]什么都能排的C语言qsort排序详解[超详细的宝藏级别教程]深度理解qsort排序 作者: @小小Programmer 这是我的主页:@小小Programmer 在食用这篇博客之前,博主在这里 ...
- Delphi - Case 可以多条件 指定在一起,今天才知道;逗号分隔