【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( ...
随机推荐
- [转帖]将nginx.conf文件的内容拆分成多个
nginx的如果有多个server模块都配置在同一个nginx.conf文件会显得比较臃肿,后续维护起来也会比较困难,所以可以将内容写入到多个配置文件中然后在nginx.conf文件中通过includ ...
- Windows命令行查看相关信息
Windows命令行查看相关信息 查看网络相关 查看网络相关 netstat -ano |findstr -v 127 |findstr -v 10.110 |findstr -v 10.6 |fin ...
- echarts显示地图
<template> <div class="managingPatientSize"> <div id="china-map"& ...
- 【一】AI Studio 项目详解【(一)VisualDL工具、环境使用说明、脚本任务、图形化任务、在线部署及预测】PARL
相关文章 [一]-环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简介 [五]-Sarsa&Qlear ...
- 4.3 C++ Boost 日期时间操作库
Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量.可移植.高效的C应用程序.Boost库可以作为标准C库的后备,通常被称为准标准 ...
- Linux 文件目录操作命令
Linux 基础的文件目录操作命令,融合多部Linux经典著作,去除多余部分,保留实用部分. 显示目录或文件: 显示目标列表,在Linux系统中是使用率较高的命令.ls命令的输出信息可以进行彩色加亮显 ...
- Intellij IDEA 中 .properties文件中文乱码
在别的地方显示正常的 application.properties 文件,放到 idea 中就会有乱码,如下图所示 idea 右下角编码那里还是灰色的,不能更改 解决方法 点开 idea 的 sett ...
- Idhttp Post https 连接 报“IOHandler value is not valid.”错误
今天研究阿里巴巴的对接,发现IDHTTP 的post 如果是 https 的连接就会报:"IOHandler value is not valid."错误 加载https的站点页面 ...
- JS Leetcode 154. 寻找旋转排序数组中的最小值 II 题解分析
壹 ❀ 引 早在10个月前,也就是去年,我记录了JS leetcode 寻找旋转排序数组中的最小值 题解分析,你不得不了解的二分法一题,那么这篇文章记录它的升级版,来自LeetCode154. 寻找旋 ...
- C语言中,指针变量的坑
先看一个初始化带头结点单链表的例子,LNode是结点变量,LinkList是结点指针变量,等同于LNode* typedef struct LNode{ // 定义单链表节点类型 int data; ...