135. 分发糖果
题目:
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
你需要按照以下要求,帮助老师给这些孩子分发糖果:
每个孩子至少分配到 1 个糖果。
评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。
那么这样下来,老师至少需要准备多少颗糖果呢?
思路:
规则定义:设学生A和学生B左右相邻,A在B左边;
左规则:当 ratingsB>ratingsA时,B的糖比 A的糖数量多。
右规则:当ratingsA>ratingsB时,A的糖比B的糖数量多。
相邻的学生中,评分高的学生必须获得更多的糖果等价于所有学生满足左规则且满足右规则。
算法流程:
先从左至右遍历学生评分ratings,按照以下规则给糖,并记录在 left 中;
先给所有学生1颗糖;
若ratingsi > ratingsi-1,则第i名学生糖比第i-1名学生多1个。
若ratingsi <= ratingsi-1,则第i名学生糖数量不变。(交由从右到左遍历时处理)
经过此规则分配后,可以保证所有学生糖数量满足左规则。
同理,在此规则下从右至左遍历学生评分并记录在 right 中,可以保证所有学生糖数量满足右规则。
最终,取以上2轮遍历 left 和 right 对应学生糖果数的最大值,这样则同时满足左规则和右规则,即得到每个同学的最少糖果数量。
代码:
class Solution {
public int candy(int[] ratings) {
if (ratings == null || ratings.length == 0) return 0;
int [] left = new int[ratings.length];
int [] right = new int[ratings.length];
//初始化糖果数为1;
Arrays.fill(left,1);
Arrays.fill(right,1);
//从左到右
for(int i = 1; i < ratings.length; i++)
{
if(ratings[i] > ratings[i-1])
{
left[i] = left[i-1] + 1;
}
}
int total = left[ratings.length-1];
//从右到左
for(int i = ratings.length-2; i >= 0; i--)
{
if(ratings[i] > ratings[i+1])
{
right[i] = right[i+1] + 1;
}
total += Math.max(left[i],right[i]);
}
return total;
}
}
参考资料:最易懂的贪心算法
转载:
如有冒犯请私信我删除
链接:https://leetcode-cn.com/problems/candy/solution/candy-cong-zuo-zhi-you-cong-you-zhi-zuo-qu-zui-da-/