135. 分发糖果
一、题目
n
个孩子站成一排。给你一个整数数组 ratings
表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到
1
个糖果。 - 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
二、思路
- 规则定义: 设学生 A和学生 B 左右相邻,A 在 B左边;
- 左规则: 当 ratingsB>ratingsA时,B 的糖比 A的糖数量多。
- 右规则: 当 ratingsA>ratingsB时,A 的糖比 B 的糖数量多。
相邻的学生中,评分高的学生必须获得更多的糖果 等价于 所有学生满足左规则且满足右规则。
我们取序列中的任意两点,A B
- 如果 A > B ,则按照左规则处理后,B不会比A多;按照右规则处理后,A一定比B多,那么A一定会被更新(变大),但L、R规则仍然成立:B不会比A多,A一定比B多;
- 同理可讨论 A<B;
- 当 A == B,A、B的值无论如何更新,都不影响 L、R规则
综上,取最大值后不影响某一规则的成立。
三、代码
class Solution: def candy(self, ratings: List[int]) -> int: left = [1 for _ in range(len(ratings))] right = left[:] for i in range(1, len(ratings)): if ratings[i] > ratings[i - 1]: left[i] = left[i - 1] + 1 count = left[-1] for i in range(len(ratings) - 2, -1, -1): if ratings[i] > ratings[i + 1]: right[i] = right[i + 1] + 1 count += max(left[i], right[i]) return count
[-1]: 列表最后一项
四、分析
-
复杂度分析:
- 时间复杂度 O(N): 遍历两遍数组即可得到结果;
- 空间复杂度 O(N) : 需要借用
left
,right
的线性额外空间。