题目描述
给你一个下标从 0 开始的整数数组 nums 和一个 非负 整数 k 。
在一步操作中,你可以执行下述指令:
- 在范围
[0, nums.length - 1]中选择一个 此前没有选过 的下标i。 - 将
nums[i]替换为范围[nums[i] - k, nums[i] + k]内的任一整数。
数组的 美丽值 定义为数组中由相等元素组成的最长子序列的长度。
对数组 nums 执行上述操作任意次后,返回数组可能取得的 最大 美丽值。
注意:你 只 能对每个下标执行 一次 此操作。
数组的 子序列 定义是:经由原数组删除一些元素(也可能不删除)得到的一个新数组,且在此过程中剩余元素的顺序不发生改变。
示例 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(整个数组)。
提示:
1 <= nums.length <= 1050 <= nums[i], k <= 105
思路一:
数组中每个数字取值范围是[nums-k,nums+k],从其中找到最大值,子序列定义非连续,数组元素顺序不影响结果,可以先进行排序。排序后对满足条件区间进行枚举取最大值。
代码
class Solution {
//排序加滑动窗口
public int maximumBeauty(int[] nums, int k) {
Arrays.sort(nums);
int res=0,n=nums.length;
for(int i=0,j=0;i<n;i++){
while(nums[i] - (k<<1) > nums[j]){
j++;
}
res=Math.max(res,i-j+1);
}
return res;
}
思路二:
差分数组其实是依据朴素思想暴力进行的优化,暴力做法会TimeOut,使用元素均为0的差分数组进行区间修改,降低时间复杂度。具体思路是对这N个数字进行遍历,每个数字对应区间【nums[x]-k,nums[x]+k】进行加1(加1代表有一个数组元素映射),遍历完成后进行找到和最大的数字即为结果
class Solution {
//差分
public int maximumBeauty(int[] nums, int k) {
int m=0;
for(int x:nums){
m=Math.max(m,x);
}
int[] diff =new int[m+2];
for(int x:nums){
diff[Math.max(x-k,0)]++;
diff[Math.min(x+k+1,m+1)]--;
}
int res=0,cnt=0;
for(int x:diff){
cnt+=x;
res=Math.max(res,cnt);
}
return res;
}
}
330

被折叠的 条评论
为什么被折叠?



