|
| 1 | +#### 2779. 数组的最大美丽值 |
| 2 | + |
| 3 | +难度:中等 |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +给你一个下标从 **0** 开始的整数数组 `nums` 和一个 **非负** 整数 `k` 。 |
| 8 | + |
| 9 | +在一步操作中,你可以执行下述指令: |
| 10 | + |
| 11 | +* 在范围 `[0, nums.length - 1]` 中选择一个 **此前没有选过** 的下标 `i` 。 |
| 12 | +* 将 `nums[i]` 替换为范围 `[nums[i] - k, nums[i] + k]` 内的任一整数。 |
| 13 | + |
| 14 | +数组的 **美丽值** 定义为数组中由相等元素组成的最长子序列的长度。 |
| 15 | + |
| 16 | +对数组 `nums` 执行上述操作任意次后,返回数组可能取得的 **最大** 美丽值。 |
| 17 | + |
| 18 | + **注意:** 你 **只** 能对每个下标执行 **一次** 此操作。 |
| 19 | + |
| 20 | +数组的 **子序列** 定义是:经由原数组删除一些元素(也可能不删除)得到的一个新数组,且在此过程中剩余元素的顺序不发生改变。 |
| 21 | + |
| 22 | + **示例 1:** |
| 23 | + |
| 24 | +``` |
| 25 | +输入:nums = [4,6,1,2], k = 2 |
| 26 | +输出:3 |
| 27 | +解释:在这个示例中,我们执行下述操作: |
| 28 | +- 选择下标 1 ,将其替换为 4(从范围 [4,8] 中选出),此时 nums = [4,4,1,2] 。 |
| 29 | +- 选择下标 3 ,将其替换为 4(从范围 [0,4] 中选出),此时 nums = [4,4,1,4] 。 |
| 30 | +执行上述操作后,数组的美丽值是 3(子序列由下标 0 、1 、3 对应的元素组成)。 |
| 31 | +可以证明 3 是我们可以得到的由相等元素组成的最长子序列长度。 |
| 32 | +``` |
| 33 | + |
| 34 | + **示例 2:** |
| 35 | + |
| 36 | +``` |
| 37 | +输入:nums = [1,1,1,1], k = 10 |
| 38 | +输出:4 |
| 39 | +解释:在这个示例中,我们无需执行任何操作。 |
| 40 | +数组 nums 的美丽值是 4(整个数组)。 |
| 41 | +``` |
| 42 | + |
| 43 | + **提示:** |
| 44 | + |
| 45 | +* `1 <= nums.length <= 10^5` |
| 46 | +* `0 <= nums[i], k <= 10^5` |
| 47 | + |
| 48 | +--- |
| 49 | + |
| 50 | +排序 + 滑动窗口: |
| 51 | + |
| 52 | +根据题目对子序列的定义,我们知道元素的顺序对数组的美丽值无影响,因此考虑先排序。 |
| 53 | + |
| 54 | +初始化窗口长度为一,并枚举右端点(右端点不断的向右移动),当右端点的下一位数与左端点的差大于两倍的 `k`,左端点向右移动一位。 |
| 55 | + |
| 56 | +这样能保证窗口长度只增不减,一定是最大美丽值。 |
| 57 | + |
| 58 | +```Go |
| 59 | +func maximumBeauty(nums []int, k int) int { |
| 60 | + sort.Ints(nums) |
| 61 | + left, right := 0, 0 |
| 62 | + for ;right < len(nums) - 1; right++ { |
| 63 | + if nums[right + 1] - nums[left] > 2 * k { |
| 64 | + left++ |
| 65 | + } |
| 66 | + } |
| 67 | + return right - left + 1 |
| 68 | +} |
| 69 | +``` |
0 commit comments