题目
n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
1、每个孩子至少分配到 1 个糖果。
2、相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
解析
题目要求返回需要的最少糖果数目,那么ratings中相邻两个元素,分数高的比分数低的多1颗糖即可,连续递增子序列的糖果好分配(多给一颗糖就行),但是问题在于递减的情况,递减时需要知道连续递减的个数,才知道要给最前面的同学分配几颗糖果,如:[1,100,10,9,8];单纯的从左往右遍历时,分数100的同学会得到2个糖果,但是就无法给[10,9,8]合理分配糖果了
注意:如果相邻的是相同分数的同学,他们的糖果并没有要求谁多谁少,可以给其中一个分配1颗糖果,或者两个同学都分配1颗糖果
思路
前后遍历+贪心
1、从前往后遍历ratings时,只考虑严格递增的情况,并保存每位同学分配到的糖果数,递减的情况交给从后往前遍历
2、从后往前遍历ratings时,也只考虑严格递增的情况,并保存每位同学分配到的糖果数,递减的情况交给从前往后遍历
3、由于至少需要一颗糖果,所以初始化所有元素值为1的left数组,用来保存从前往后遍历分配的糖果数;初始化所有元素值为1的right数组,用来保存从后往前遍历分配的糖果数
4、每一位同学应该分配的糖果数应该是max(left[i], right[i])
图解
python代码
class Solution:
def candy(self, ratings):
# 思路: 前后遍历 + 贪心
n = len(ratings)
left = [1] * n
right = left[:]
ans = 0
for i in range(1, n):
# 从左往右遍历
if ratings[i] > ratings[i - 1]: # 右边分数大于左边,只要比左边多一颗糖
left[i] = left[i - 1] + 1
for j in range(n - 2, -1, -1):
# 从右往左遍历
if ratings[j] > ratings[j + 1]: # 左边分数大于右边,左边比右边多一颗糖
right[j] = right[j + 1] + 1
ans += max(left[j], right[j])
ans += max(left[n - 1], right[n - 1])
return ans