贪心猫的鱼干大分配 | 豆包MarsCode AI刷题

38 阅读2分钟

问题描述

在猫星球上,小R负责给一行排队的猫分发鱼干。每只猫有一个等级,等级越高的猫应该得到更多的鱼干。规则如下:

  1. 每只猫至少得到一斤鱼干。
  2. 如果一只猫的等级高于它相邻的猫,它就应该得到比相邻的猫更多的鱼干。

小R想知道,为了公平地满足所有猫的等级差异,他至少需要准备多少斤鱼干。

分析

我们可以使用一个数组 amounts 来记录每只猫分配到的鱼干数量。初始时,每只猫至少得到一斤鱼干,所以 amounts 可以初始化为 [1] * n

amounts = [1]*n

相邻有两种情况,左相邻和右相邻,那么我们可以将其分开考虑,使用两次不同方向的遍历,再将结果累计起来,实现目的。

  1. 从左到右遍历:确保每只猫的鱼干数量满足其等级高于左边相邻猫的情况。对于每只猫 behind,如果它的等级高于左边的猫 behind-1,则 amounts[behind] 应该至少比 amounts[behind-1] 多 1。(因为是与左边的进行比较,behind1开始,到n - 1结束)
for behind in range(1,n):#从左往右遍历
        if cats_levels[behind] > cats_levels[behind - 1]:
            amounts[behind] = amounts[behind - 1] + 1

2. 从右到左遍历:确保每只猫的鱼干数量满足其等级高于右边相邻猫的情况。 对于每只猫 i,如果它的等级高于右边的猫 i+1,则 amounts[i] 应该至少比 amounts[i+1] 多 1。(因为是与右边的进行比较,in - 2开始,到0结束)

for i in range(n - 2, -1, -1):#从右往左遍历
        if cats_levels[i] > cats_levels[i + 1]:
            amounts[i] = max(amounts[i], amounts[i + 1] + 1)

通过两次不同方向上的遍历,我们可以不断更新数据,确保每只猫的鱼干数量满足题目要求。最后,计算 amounts 数组的总和即为所需的最少鱼干数量。

代码

def solution(n, cats_levels):
    amounts = [1]*n
    for behind in range(1,n):#从左往右遍历
        if cats_levels[behind] > cats_levels[behind - 1]:
            amounts[behind] = amounts[behind - 1] + 1
    for i in range(n - 2, -1, -1):#从右往左遍历
        if cats_levels[i] > cats_levels[i + 1]:
            amounts[i] = max(amounts[i], amounts[i + 1] + 1)
    return sum(amounts)

测试样例

if __name__ == "__main__":
    cats_levels1 = [1, 2, 2]
    cats_levels2 = [6, 5, 4, 3, 2, 16]
    cats_levels3 = [1, 2, 2, 3, 3, 20, 1, 2, 3, 3, 2, 1, 5, 6, 6, 5, 5, 7, 7, 4]
    print(solution(3, cats_levels1) == 4)
    print(solution(6, cats_levels2) == 17)
    print(solution(20, cats_levels3) == 35)

image.png

结果正确且提交成功。

总结

两次遍历法这种方法通常用于确保每个元素都与其相邻元素进行比较。你可以先从左到右遍历一次,然后再从右到左遍历一次,两次操作结果的叠加就可以确保每个元素都满足条件。