题目:
给你一个下标从 0 开始的整数数组 nums 和一个 非负 整数 k 。
在一步操作中,你可以执行下述指令:
- 在范围
[0, nums.length - 1]中选择一个 此前没有选过 的下标i。 - 将
nums[i]替换为范围[nums[i] - k, nums[i] + k]内的任一整数。
数组的 美丽值 定义为数组中由相等元素组成的最长子序列的长度。
对数组 nums 执行上述操作任意次后,返回数组可能取得的 最大 美丽值。
注意: 你 只 能对每个下标执行 一次 此操作。
数组的 子序列 定义是:经由原数组删除一些元素(也可能不删除)得到的一个新数组,且在此过程中剩余元素的顺序不发生改变。
算法:
方法一:暴力
TLE
func maximumBeauty(nums []int, k int) int {
numCount := make(map[int]int, 0)
ans := 0
for i := range nums {
low, high := nums[i] - k, nums[i] + k
low = max(low, 0)
high = min(100000, high)
// fmt.Println(low, high)
for j := low; j <= high; j ++ {
numCount[j] ++
if numCount[j] > ans {
ans = numCount[j]
}
}
}
// fmt.Println(numCount)
// if ans == 0 {
// return 1
// }
return ans
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
方法二:前缀和
用前缀和计算数字出现的次数。
[low,high]的范围为:[1-10^5, 210^5],右移之后的范围为:[1, 310^5]
func maximumBeauty(nums []int, k int) int {
ans := 0
numCountDiff := make([]int, 300002)
for i := range nums {
low, high := nums[i] - k, nums[i] + k
low = low + 100000
high = high + 100000
// fmt.Println(low, high)
numCountDiff[low] ++
numCountDiff[high + 1] --
}
count := 0
for i := range numCountDiff {
count = count + numCountDiff[i]
if count > ans {
ans = count
}
}
return ans
}