135. 分发糖果

一、题目

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

  • 每个孩子至少分配到 1 个糖果。
  • 相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

二、思路

  • 规则定义: 设学生 A和学生 B 左右相邻,A 在 B左边;
    • 左规则: 当 ratingsB>ratingsA时,B 的糖比 A的糖数量多。
    • 右规则: 当 ratingsA>ratingsB时,A 的糖比 B 的糖数量多。

相邻的学生中,评分高的学生必须获得更多的糖果 等价于 所有学生满足左规则且满足右规则。

我们取序列中的任意两点,A B

  1. 如果 A > B ,则按照左规则处理后,B不会比A多;按照右规则处理后,A一定比B多,那么A一定会被更新(变大),但L、R规则仍然成立:B不会比A多,A一定比B多;
  2. 同理可讨论 A<B;
  3. 当 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) : 需要借用 leftright 的线性额外空间。
posted @ 2023-02-22 18:39  ImreW  阅读(5)  评论(0编辑  收藏  举报