There are N children standing in a line. Each child is assigned a rating value.

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

What is the minimum candies you must give?

这道题看起来很难,其实解法并没有那么复杂,当然我也是看了别人的解法才做出来的,先来看看两遍遍历的解法,首先初始化每个人一个糖果,然后这个算法需要遍历两遍,第一遍从左向右遍历,如果右边的小盆友的等级高,等加一个糖果,这样保证了一个方向上高等级的糖果多。然后再从右向左遍历一遍,如果相邻两个左边的等级高,而左边的糖果又少的话,则左边糖果数为右边糖果数加一。最后再把所有小盆友的糖果数都加起来返回即可。代码如下:

解法一:

class Solution {
public:
int candy(vector<int>& ratings) {
int res = , n = ratings.size();
vector<int> nums(n, );
for (int i = ; i < n - ; ++i) {
if (ratings[i + ] > ratings[i]) nums[i + ] = nums[i] + ;
}
for (int i = n - ; i > ; --i) {
if (ratings[i - ] > ratings[i]) nums[i - ] = max(nums[i - ], nums[i] + );
}
for (int num : nums) res += num;
return res;
}
};

下面来看一次遍历的方法,相比于遍历两次的思路简单明了,这种只遍历一次的解法就稍有些复杂了。首先我们给第一个同学一个糖果,那么对于接下来的一个同学就有三种情况:

1. 接下来的同学的rating等于前一个同学,那么给接下来的同学一个糖果就行。

2. 接下来的同学的rating大于前一个同学,那么给接下来的同学的糖果数要比前一个同学糖果数加1。

3.接下来的同学的rating小于前一个同学,那么我们此时不知道应该给这个同学多少个糖果,需要看后面的情况。

对于第三种情况,我们不确定要给几个,因为要是只给1个的话,那么有可能接下来还有rating更小的同学,总不能一个都不给吧。也不能直接给前一个同学的糖果数减1,有可能给多了,因为如果后面再没人了的话,其实只要给一个就行了。还有就是,如果后面好几个rating越来越小的同学,那么前一个同学的糖果数可能还得追加,以保证最后面的同学至少能有1个糖果。来一个例子吧,四个同学,他们的rating如下:

1 3 2 1

先给第一个rating为1的同学一个糖果,然后从第二个同学开始遍历,第二个同学rating为3,比1大,所以多给一个糖果,第二个同学得到两个糖果。下面第三个同学,他的rating为2,比前一个同学的rating小,如果我们此时给1个糖果的话,那么rating更小的第四个同学就得不到糖果了,所以我们要给第四个同学1个糖果,而给第三个同学2个糖果,此时要给第二个同学追加1个糖果,使其能够比第三个同学的糖果数多至少一个。那么我们就需要统计出多有个连着的同学的rating变小,用变量cnt来记录,找出了最后一个减小的同学,那么就可以往前推,每往前一个加一个糖果,这就是个等差数列,我们可以直接利用求和公式算出这些rating减小的同学的糖果之和。然后我们还要看第一个开始减小的同学的前一个同学需不需要追加糖果,只要比较cnt和pre的大小,pre是之前同学得到的最大糖果数,二者做差加1就是需要追加的糖果数,加到结果res中即可,参见代码如下:

解法二:

class Solution {
public:
int candy(vector<int>& ratings) {
if (ratings.empty()) return ;
int res = , pre = , cnt = ;
for (int i = ; i < ratings.size(); ++i) {
if (ratings[i] >= ratings[i - ]) {
if (cnt > ) {
res += cnt * (cnt + ) / ;
if (cnt >= pre) res += cnt - pre + ;
cnt = ;
pre = ;
}
pre = (ratings[i] == ratings[i - ]) ? : pre + ;
res += pre;
} else {
++cnt;
}
}
if (cnt > ) {
res += cnt * (cnt + ) / ;
if (cnt >= pre) res += cnt - pre + ;
}
return res;
}
};

参考资料:

https://discuss.leetcode.com/topic/5243/a-simple-solution

https://discuss.leetcode.com/topic/8208/one-pass-constant-space-java-solution

https://discuss.leetcode.com/topic/17722/two-c-solutions-given-with-explanation-both-with-o-n-time-one-with-o-1-space-the-other-with-o-n-space

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Candy 分糖果问题的更多相关文章

  1. [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现

    [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现 原题: There are N children standing in a line. ...

  2. Java实现 LeetCode 575 分糖果(看看是你的长度小还是我的种类少)

    575. 分糖果 给定一个偶数长度的数组,其中不同的数字代表着不同种类的糖果,每一个数字代表一个糖果.你需要把这些糖果平均分给一个弟弟和一个妹妹.返回妹妹可以获得的最大糖果的种类数. 示例 1: 输入 ...

  3. [LeetCode] Candy Crush 糖果消消乐

    This question is about implementing a basic elimination algorithm for Candy Crush. Given a 2D intege ...

  4. [LintCode] Candy 分糖果问题

    There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...

  5. Leetcode 135.分糖果

    分发糖果 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分. 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果. 相邻的孩 ...

  6. LeetCode 1103. Distribute Candies to People (分糖果 II)

    题目标签:Math 题目让我们分发糖果,分的糖果从1 开始依次增加,直到分完. for loop可以计数糖果的数量,直到糖果发完.但是还是要遍历array 给people 发糖,这里要用到 index ...

  7. leetcode — candy

    /** * Source : https://oj.leetcode.com/problems/candy/ * * There are N children standing in a line. ...

  8. 蓝桥杯 历届试题 PREV-32 分糖果

    历届试题 分糖果   时间限制:1.0s   内存限制:256.0MB 问题描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一半给左手边 ...

  9. CSDN 分糖果算法的思路和求助

    昨天晚上 在csdn上做了一道分糖果的题目,我自个测的是没有问题,但是提交答案后,老失败,提示 你的程序正常运行并输出了结果,但是答案错误你的程序输出结果与测试数据中的输出结果不符 我先把自个思路说一 ...

随机推荐

  1. C#的Process类调用第三方插件实现PDF文件转SWF文件

    在项目开发过程中,有时会需要用到调用第三方程序实现本系统的某一些功能,例如本文中需要使用到的swftools插件,那么如何在程序中使用这个插件,并且该插件是如何将PDF文件转化为SWF文件的呢?接下来 ...

  2. 文本框focus之后高亮背景颜色

    看效果:Html: CSS: jQuery: 或者使用连写法:

  3. DateHelper.cs日期时间操作辅助类C#

    //==================================================================== //** Copyright © classbao.com ...

  4. 阅读微信支付demo收获

       1,公司现有系统有很多,存放重要接口的日志分布在不同的库,每个系统都有单独的日志采集表,日志采集模块:        ????         这些日志可以统一放到一个地方,通过一个组件提供出去 ...

  5. Jedis的使用

    Redis是常用的key-value存储服务器,Java使用Redis有很多方法,其中官方推荐的是Jedis. 使用Jedis,首先是下载jedis-x.x.x.jar文件并导入工程,然后运行Redi ...

  6. BestCoder Round #89 B题---Fxx and game(单调队列)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5945     问题描述 输入描述 输出描述 输入样例 输出样例 题意:中文题,不再赘述: 思路:  B ...

  7. nginx+lua

    一场电闪与雷鸣的结合, 公司原有服务器已经配置好nginx,需要重新装载lua模块,哈哈哈,无法无法.   安装LUA模块需要以下 pcre       ftp://ftp.csx.cam.ac.uk ...

  8. mysql常处理用时间sql语句

    Mysql日期函数,时间函数使用的总结,以及时间加减运算(转) select timediff('23:40:00', ' 18:30:00'); -- 两时间相减SELECT substring( ...

  9. 新手入门Underscore.js 中文(template)

    Underscore.js是一个很精干的库,压缩后只有4KB.它提供了几十种函数式编程的方法,弥补了标准库的不足,大大方便了javaScript的编程.MVC框架Backbone.js就将这个库作为自 ...

  10. STSDB、NDataBase 对象数据库在不同.net framework下无法读取的解决办法

    STSDB.NDataBase 等对象数据库将对象保存在文件中后,如果在不同的windows平台.不同的.net frameWork下总是无法读取,原因是对象模式已经不同了. 解决的办法也很简单,就是 ...