题解详解
56 贪心猫的鱼干大分配
问题分析
在本题中,我们需要根据猫的等级规则,分配最少的鱼干,使得所有猫都能公平获得相应的鱼干数量。规则的核心是满足以下两点:
- 每只猫至少获得 1 斤鱼干(基础条件)。
- 若某只猫的等级高于其相邻的猫,则其鱼干数量也必须大于相邻猫的鱼干数量(相邻规则)。
我们可以使用贪心法结合两次遍历的方式,动态调整鱼干的分配,使得最终分配满足规则且鱼干总量最少。
解题思路
核心思路:
-
初始化所有猫的鱼干为 1(因为每只猫至少要得到 1 斤)。
-
然后分别从左到右、从右到左两次遍历,通过调整鱼干分配,使得每只猫满足相邻关系的规则:
- 左到右遍历:确保当前猫的鱼干比左侧等级低的猫多。
- 右到左遍历:确保当前猫的鱼干比右侧等级低的猫多。
通过这两次调整,每只猫都会根据自己的等级得到正确的鱼干分配,同时满足两侧相邻的规则。
算法步骤
-
初始化:
- 创建一个数组
fish,表示每只猫分配的鱼干数量,初始值为 1(每只猫至少分得 1 斤鱼干)。 - 遍历过程中,动态调整数组中每个位置的值。
- 创建一个数组
-
从左到右遍历:
- 若当前猫的等级高于前一只猫,则当前猫的鱼干数量比前一只猫多 1。
-
从右到左遍历:
- 若当前猫的等级高于后一只猫,并且当前鱼干数量不足以满足规则,则将当前猫的鱼干调整为比后一只猫多 1。
-
求和:
- 最终将数组
fish中的所有元素相加,得到最少所需的鱼干总量。
- 最终将数组
示例代码
def min_fish_dry(n, cats_levels):
# 初始化每只猫的鱼干数量为 1
fish = [1] * n
# 从左到右遍历,满足左规则
for i in range(1, n):
if cats_levels[i] > cats_levels[i - 1]:
fish[i] = fish[i - 1] + 1
# 从右到左遍历,满足右规则
for i in range(n - 2, -1, -1):
if cats_levels[i] > cats_levels[i + 1]:
fish[i] = max(fish[i], fish[i + 1] + 1)
# 返回总鱼干数量
return sum(fish)
# 测试样例
print(min_fish_dry(3, [1, 2, 2])) # 输出: 4
print(min_fish_dry(6, [6, 5, 4, 3, 2, 16])) # 输出: 17
print(min_fish_dry(20, [1, 2, 2, 3, 3, 20, 1, 2, 3, 3, 2, 1, 5, 6, 6, 5, 5, 7, 7, 4])) # 输出: 35
示例解析
示例 1
输入:n = 3, cats_levels = [1, 2, 2]
初始化:
fish = [1, 1, 1](每只猫先分 1 斤鱼干)。
从左到右遍历:
- 第 2 只猫等级比第 1 只高,因此
fish[1] = fish[0] + 1 = 2,fish = [1, 2, 1]。 - 第 3 只猫等级不高于第 2 只,保持不变,
fish = [1, 2, 1]。
从右到左遍历:
- 第 2 只猫等级比第 3 只高,但鱼干数量已经满足相邻规则,保持不变。
- 第 1 只猫也已经满足规则,不做调整。
结果:
总鱼干数量为 1 + 2 + 1 = 4。
示例 2
输入:n = 6, cats_levels = [6, 5, 4, 3, 2, 16]
初始化:
fish = [1, 1, 1, 1, 1, 1]。
从左到右遍历:
- 第 6 只猫等级比第 5 只猫高,
fish[5] = fish[4] + 1 = 2,fish = [1, 1, 1, 1, 1, 2]。
从右到左遍历:
- 第 5 只猫等级比第 6 只低,保持不变。
- 依次调整其他猫的鱼干数量,使得每只猫都满足相邻关系规则:
fish = [5, 4, 3, 2, 1, 2]。
结果:
总鱼干数量为 5 + 4 + 3 + 2 + 1 + 2 = 17。
复杂度分析
-
时间复杂度:
- 两次遍历数组,时间复杂度为 。
-
空间复杂度:
- 使用一个长度为 n 的数组存储分配的鱼干数量,空间复杂度为 O(n)。如果直接修改输入数组,空间复杂度可优化为 O(1)。
总结
本题利用贪心策略和两次遍历的动态调整方法,能够高效地解决问题。通过明确规则和分步调整,保证每只猫的鱼干分配满足公平性和等级差异性,同时最小化总鱼干数量。该解法简单直观,适用于类似资源分配优化的问题,如工资分配、奖励分配等场景。