小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
问题描述
现在有一群孩子做游戏,请你根据游戏得分来发糖果,要求如下:
-
每个孩子不管得分多少,起码分到一个糖果。
-
任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果。(若相同则无此限制)
给定一个数组arr代表得分数组,那你根据规则分配糖果最少需要多少颗呢?
分析问题
首先,我们可以把题目的第二条规则拆分来看一下。对于任意相邻的孩子之间,我们可以拆分为左孩子和右孩子。
- 左规则:当左孩子ratings[i-1]<ratings[i]时,当前孩子i的糖果数量要比它的左孩子i-1的多。
- 右规则:当右孩子ratings[i+1]<ratings[i]时,当前孩子i的糖果数量要比它的右孩子i+1的多。
我们通过遍历两遍数组,分别求出每个孩子在满足左规则和右规则时,最少需要的糖果数量left、right。那么每个孩子最终分得的糖果数量就为这两个值left、right的最大值,即max(left,right)。下面我们来看一下代码实现。
def candy_count(ratings):
n = len(ratings)
# 用来保存满足左规则所需要的最少的糖果数
left = [1] * n
for i in range(1, n):
if ratings[i] > ratings[i - 1]:
left[i] = left[i - 1] + 1
right = result = max(left[n-1],1)
for i in range(n - 2, -1, -1):
if ratings[i] > ratings[i + 1]:
right += 1
else:
right = 1
result += max(left[i], right)
return result
s=[1,3,5,3,2,1]
print(candy_count(s))
我们来看一下算法的复杂度。
- 时间复杂度:O(n),其中n是孩子的数量。我们需要遍历两遍数组来求出满足规则所需要的最少糖果数。
- 空间复杂度:O(n)。