问题描述
在猫星球上,小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。
- 等级高的猫得到更多的鱼干:如果一只猫的等级高于它相邻的猫,那么它的鱼干数应该比相邻的猫多。
数据结构选择
我们可以使用一个数组 resultArr 来记录每只猫应该得到的鱼干数。数组的索引对应猫的位置,数组的值对应猫的鱼干数。
算法步骤
- 初始化:创建一个与
ratings数组长度相同的resultArr,初始值为1,因为每只猫至少得到一斤鱼干。 - 从左到右遍历:从左到右遍历
ratings数组,如果当前猫的等级高于它左边的猫,那么它的鱼干数应该比左边的猫多1。 - 从右到左遍历:从右到左遍历
ratings数组,如果当前猫的等级高于它右边的猫,那么它的鱼干数应该比右边的猫多1,但要确保不小于之前计算的值。 - 计算总数:遍历
resultArr,累加所有猫的鱼干数,得到最终结果。
复杂度分析
- 时间复杂度:O(n),因为我们只需要遍历数组两次。
- 空间复杂度:O(n),因为我们使用了一个额外的数组
resultArr来存储每只猫的鱼干数。
代码
以下为golang版本的代码,暂时未通过评测(还没上线)
package main
import "fmt"
import "math"
func solution(n int, ratings []int) int {
if len(ratings) == 1 {
return 1
}
// 桶排序
ratingsBucket := make([][]int, 20001)
for key, value := range ratings {
ratingsBucket[value] = append(ratingsBucket[value], key)
}
resultArr := make([]int, len(ratings))
for _, value := range ratingsBucket {
if len(value) == 0 {
continue
}
tempResultArr := make([]int, len(resultArr))
copy(tempResultArr, resultArr)
for _, val := range value {
if val == 0 {
if ratings[val] > ratings[val+1] {
resultArr[val] = tempResultArr[val+1] + 1
} else {
resultArr[val] = 1
}
} else if val == len(ratings)-1 {
if ratings[val] > ratings[val-1] {
resultArr[val] = tempResultArr[val-1] + 1
} else {
resultArr[val] = 1
}
} else {
resultArr[val] = int(math.Max(float64(tempResultArr[val+1]), float64(tempResultArr[val-1])) + 1)
}
}
}
result := 0
for _, val := range resultArr {
result += val
}
return result
}
func main() {
// You can add more test cases here
catsLevels1 := []int{1, 2, 2}
catsLevels2 := []int{6, 5, 4, 3, 2, 16}
catsLevels3 := []int{1, 2, 2, 3, 3, 20, 1, 2, 3, 3, 2, 1, 5, 6, 6, 5, 5, 7, 7, 4}
fmt.Println(solution(3, catsLevels1) == 4)
fmt.Println(solution(6, catsLevels2) == 17)
fmt.Println(solution(20, catsLevels3) == 35)
}
以下是使用marscode翻译而来的python代码,已通过评测
import math
def solution(n, ratings):
if len(ratings) == 1:
return 1
# 桶排序
ratings_bucket = [[] for _ in range(20001)]
for key, value in enumerate(ratings):
ratings_bucket[value].append(key)
result_arr = [0] * len(ratings)
for value in ratings_bucket:
if len(value) == 0:
continue
temp_result_arr = result_arr[:]
for val in value:
if val == 0:
if ratings[val] > ratings[val + 1]:
result_arr[val] = temp_result_arr[val + 1] + 1
else:
result_arr[val] = 1
elif val == len(ratings) - 1:
if ratings[val] > ratings[val - 1]:
result_arr[val] = temp_result_arr[val - 1] + 1
else:
result_arr[val] = 1
else:
result_arr[val] = max(temp_result_arr[val + 1], temp_result_arr[val - 1]) + 1
result = sum(result_arr)
return result
if __name__ == "__main__":
# You can add more test cases here
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)
总结
从题目名称也可以看出这是一道贪心的题目,贪心题目主要难点就是发现这是一道贪心的题目,发现之后基本就是常识模拟题了。