LC每日一题|20240615 - 2779. 数组的最大美丽值
给你一个下标从 0 开始的整数数组
nums和一个 非负 整数k。在一步操作中,你可以执行下述指令:
- 在范围
[0, nums.length - 1]中选择一个 此前没有选过 的下标i。- 将
nums[i]替换为范围[nums[i] - k, nums[i] + k]内的任一整数。数组的 美丽值 定义为数组中由相等元素组成的最长子序列的长度。
对数组
nums执行上述操作任意次后,返回数组可能取得的 最大 美丽值。注意: 你 只 能对每个下标执行 一次 此操作。
数组的 子序列 定义是:经由原数组删除一些元素(也可能不删除)得到的一个新数组,且在此过程中剩余元素的顺序不发生改变。
提示:
- 1 <= nums.length <= 10^5
- 0 <= nums[i], k <= 10^5
解题思路
由于电脑一直没拿回来,所以虽然看到这题的第一时间就想到了差分,但是一直没写。
直接差分的话需要开 nums[i] + 2 * k 大小的数组,虽然时间复杂度还是O(n),但是如果不做处理无脑跑的话是会tle的(别问我怎么知道)。
观察题目,我们不难发现,操作后数组中满足条件的相等元素一定可以落在nums[i]的取值范围内。所以我们只需要关注定义域内的差分下标即可。但是由于差分每一位都是前一位推出来的,所以取值范围外的差分值也有意义,不能随意忽略。但毕竟只涉及累加操作,所以可以在跑的过程中把定义域外的就先加到一起,这样能省出很大的空间~
AC代码
class Solution {
fun maximumBeauty(nums: IntArray, k: Int): Int {
val arr = IntArray(100002)
for (i in nums.indices) {
arr[Math.max(nums[i] - k, 0)]++
arr[Math.min(nums[i] + k + 1, 100001)]--
}
for (i in 1 until arr.size) arr[i] += arr[i - 1]
return arr.max()
}
}
碎碎念
电脑本来只是触控板有点问题,周四晚上送到三里屯苹果店,今天下午就打电话来说搞定了,速度还是很快的~
拿到机器后发现C面完全换掉了,当然也包括电池和键盘。因为我有AC+,所以一切都是免费的,开心~