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 * 104
0 <= ratings[i] <= 2 * 104
贪心算法。
方法一:孩子的rate和candy需要满足的关系是,相邻孩子中rate高的那一个会分的更多的candy。如果同时考虑3,4,5等等个孩子,会混乱。故选择两次遍历的方法。
第一次遍历:从左往右,如果右孩子的rate>左孩子,右孩子的糖果=左孩子的糖果+1;
第二次遍历:从右往左,如果左孩子的rate>右孩子,左孩子的糖果=右孩子的糖果+1;
需要一个n维数组存储每个孩子的糖果数,空间复杂度o(n),时间复杂度o(n);
class Solution {
public int candy(int[] ratings) {
int candies = ratings.length;
int [] candy = new int [ratings.length];
for(int i=1; i<ratings.length; i++){
if(ratings[i]>ratings[i-1]){
candy[i] =candy[i-1] + 1;
}
}
for(int i=ratings.length-1; i>0; i--){
if(ratings[i-1]>ratings[i]){
if(candy[i]>=candy[i-1]){
candy[i-1]=candy[i]+1;
}
}
}
for(int i=0; i<candy.length; i++){
candies += candy[i];
}
return candies;
}
}
方法2:如果时间复杂度为o(1)呢?不用数组记录每个孩子的糖果,直接算经过每个孩子时,总的糖果数要增加的值。
一个很巧妙的方法。具体分析如下:
情况1
rate递增:1,2,3,4,5;
candy数: 1,2,3,4,5;
情况2
rate递减:5,4,3,2,1;
candy数: 5,4,3,2,1;
可以看作:1,2,3,4,5;
对于孩子0,先给1糖,
孩子2和1对比,比之小,则其实孩子2:1,孩子1:2;
孩子3和2对比,比之小,则其实孩子1:3,孩子2:2,孩子3:1;
因为孩子至少要有1糖的,用一种倒序的方法看,则每次递减后 加上的数 是当前递减的次数。
情况3
不增不减趋势持平:由样例2知,给1
情况4
举例:
1,2,3,4,5,6,7,8
3,4,5,4,3,2,1,0
按照上方的推断,每个孩子得到的糖果应为: 1,2,3,5,4,3,2,1
可以发现,3孩子和4孩子的糖果数满足条件。这是因为递增的次数为3,而当分到6孩子时,递减的次数已经等于递增的次数了,这个时候,应该给递增的最后一个孩子+一个糖;如果递减的次数>递增的怎么办?继续加糖。(倒序着看就明了了)
设置inc(增加的次数),dec(减少的次数),以及candy数,pre(当前的糖果数)
部分代码如下
**情况1+3**
if(ratings[i]>=ratings[i-1]){
dec = 0;
pre = ratings[i]==ratings[i-1] ? 1:pre+1;
candy += pre;
inc = pre;
**情况2+4**
else{
dec ++;
if(dec==inc){
dec++; // 倒序,相当于为inc中最后 dec超过inc的数目 的孩子加了糖。
}
candy += dec;
pre = 1;
}
完整代码
class Solution {
public int candy(int[] ratings) {
int inc = 1;
int dec = 0;
int candy = 1;
int pre = 1;
for(int i=1; i<ratings.length; i++){
if(ratings[i]>=ratings[i-1]){
dec = 0;
pre = ratings[i]==ratings[i-1] ? 1:pre+1;
candy += pre;
inc = pre;
}else{
dec ++;
if(dec==inc){
dec++;
}
candy += dec;
pre = 1;
}
}
return candy;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix