LC每日一题|20240615 - 2779. 数组的最大美丽值

84 阅读2分钟

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+,所以一切都是免费的,开心~