您现在的位置是:首页 >技术教程 >[HOT 100] 2779. 数组的最大美丽值网站首页技术教程

[HOT 100] 2779. 数组的最大美丽值

水蓝烟雨 2025-08-24 12:01:04
简介[HOT 100] 2779. 数组的最大美丽值

1. 题目链接


2779. 数组的最大美丽值 - 力扣(LeetCode)


2. 题目描述


给你一个下标从 0 开始的整数数组 nums 和一个 非负 整数 k

在一步操作中,你可以执行下述指令:

  • 在范围 [0, nums.length - 1] 中选择一个 此前没有选过 的下标 i
  • nums[i] 替换为范围 [nums[i] - k, nums[i] + k] 内的任一整数。

数组的 美丽值 定义为数组中由相等元素组成的最长子序列的长度。

对数组 nums 执行上述操作任意次后,返回数组可能取得的 最大 美丽值。

注意:你 只 能对每个下标执行 一次 此操作。

子序列 定义是:经由原数组删除一些元素(也可能不删除)得到的一个新数组,且在此过程中剩余元素的顺序不发生改变。

3. 题目示例


示例 1 :

输入:nums = [4,6,1,2], k = 2
输出:3
解释:在这个示例中,我们执行下述操作:
- 选择下标 1 ,将其替换为 4(从范围 [4,8] 中选出),此时 nums = [4,4,1,2] 。
- 选择下标 3 ,将其替换为 4(从范围 [0,4] 中选出),此时 nums = [4,4,1,4] 。
执行上述操作后,数组的美丽值是 3(子序列由下标 0 、1 、3 对应的元素组成)。
可以证明 3 是我们可以得到的由相等元素组成的最长子序列长度。

示例 2 :

输入:nums = [1,1,1,1], k = 10
输出:4
解释:在这个示例中,我们无需执行任何操作。
数组 nums 的美丽值是 4(整个数组)。

4. 解题思路


这道题的关键在于,最大子数组的美丽值 可以通过 滑动窗口(双指针)技巧来实现。基本思路是:

  1. 排序:首先对数组进行排序,这样可以确保窗口内的元素是有序的。排序后,若某个子数组中的最大值与最小值的差值不超过 2 * k,则说明该子数组内的所有元素的差值也必然符合条件。
  2. 滑动窗口:使用两个指针 leftrightright 用来扩展窗口,left 用来收缩窗口。通过动态调整窗口的大小,确保窗口内元素的差值不超过 2 * k
  3. 更新答案:每次扩展右指针时,检查当前窗口是否符合条件,如果符合条件,更新最大长度。

5. 题解代码


class Solution {
    public int maximumBeauty(int[] nums, int k) {
        Arrays.sort(nums);  // 对数组进行排序
        int ans = 0, left = 0;
        
        // 右指针遍历整个数组
        for(int right = 0; right < nums.length; right++){
            // 如果当前窗口内的最大值与最小值的差超过 2 * k,则收缩窗口
            while(nums[right] - nums[left] > k * 2){
                left++;  // 移动左指针
            }
            // 更新答案,记录当前窗口的最大长度
            ans = Math.max(ans, right - left + 1);
        }
        
        return ans;  // 返回最大子数组长度
    }
}


6. 复杂度分析


  • 时间复杂度O(n log n),其中 n 是数组 nums 的长度。排序的时间复杂度为 O(n log n),而滑动窗口的遍历时间复杂度为 O(n)。因此,总时间复杂度为 O(n log n)
  • 空间复杂度O(1),算法使用了常数的额外空间,除了输入数组外,不需要额外的空间。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。