问题描述
在猫星球上,小R负责给一行排队的猫分发鱼干。每只猫有一个等级,等级越高的猫应该得到更多的鱼干。规则如下:
- 每只猫至少得到一斤鱼干。
- 如果一只猫的等级高于它相邻的猫,它就应该得到比相邻的猫更多的鱼干。
小R想知道,为了公平地满足所有猫的等级差异,他至少需要准备多少斤鱼干。
测试样例
样例1:
输入:
n = 3, cats_levels = [1, 2, 2]
输出:4
样例2:
输入:
n = 6, cats_levels = [6, 5, 4, 3, 2, 16]
输出:17
样例3:
输入:
n = 20, cats_levels = [1, 2, 2, 3, 3, 20, 1, 2, 3, 3, 2, 1, 5, 6, 6, 5, 5, 7, 7, 4]
输出:35
对于这题目,我们先分析一下题意,
问题分析
给定猫的等级列表,每只猫至少需要得到 1 斤鱼干。如果一只猫的等级比其相邻的猫高,它应该得到更多的鱼干。我们的目标是找出最少需要准备多少鱼干,满足这些规则。
解决思路
- 初始化:由于每只猫至少得到 1 斤鱼干,所以我们先创建一个数组
fish
,该数组的每个元素初始化为 1,表示每只猫最初获得的鱼干数。 - 左到右扫描:第一次扫描时,我们从左到右遍历猫的等级列表。如果当前猫的等级比前一只猫的等级高(
cats_levels[i] > cats_levels[i-1]
),根据题意,它需要比前一只猫多 1 斤鱼干。因此,我们可以将当前猫的鱼干数设为前一只猫的鱼干数加 1,即fish[i] = fish[i-1] + 1
。 - 右到左扫描:在左到右扫描之后,可能会有一些猫的鱼干数没有满足与右边猫的等级差异要求。所以,我们再从右到左进行一次扫描。如果当前猫的等级比下一只猫高,并且当前猫的鱼干数没有比下一只猫多,那么我们就更新当前猫的鱼干数为下一只猫的鱼干数加 1,即
fish[i] = max(fish[i], fish[i+1] + 1)
。这里使用max
是因为在左到右扫描时,当前猫的鱼干数已经被设定过了,我们要确保这次扫描不会减少鱼干数,而是通过对比来取最大值。 - 计算总鱼干数:经过两次扫描后,我们就得到了每只猫的鱼干数,最后我们只需将它们加起来,得到最少需要准备的总鱼干数。
贪心策略的正确性
- 最小化鱼干数:从左到右和从右到左的扫描都是局部的贪心选择,确保每只猫在符合条件的情况下得到最少的鱼干数。
- 单次调整后不会降低结果:我们第一次从左到右扫描时,确保了每只猫在相对较大的等级差异下获得足够的鱼干数。然后,第二次从右到左的扫描,只会根据右边猫的鱼干数进行必要的调整,确保满足右侧相邻猫的等级差异要求。
时间复杂度
- 初始化数组的时间复杂度是 O(n),其中 n 是猫的数量。
- 从左到右的扫描时间复杂度是 O(n)。
- 从右到左的扫描时间复杂度也是 O(n)。
- 最终求和的时间复杂度是 O(n)。
那么分析到这,我们就可以写Py代码了: