给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。
如果子数组中所有元素都相等,则认为子数组是一个 等值子数组 。注意,空数组是 等值子数组 。
从 nums 中删除最多 k 个元素后,返回可能的最长等值子数组的长度。
子数组 是数组中一个连续且可能为空的元素序列。
输入:nums = [1,3,2,3,1,3], k = 3 输出:3
- 记录所有等值子数组的每个元素在nums中对应的位置于position表
- 遍历position表,pos[right]-pos[left]的应该大于或等于right-left,大于的值应该小于或等于k,k为能更改的次数嘛,不同的我就改
- pos[right]-pos[left]-(right-left)>k时移动pos中的left
class Solution {
public:
int longestEqualSubarray(vector<int>& nums, int k) {
int n=nums.size();int res=1;
vector<vector<int>> position(n+1);
for(int i=0;i<n;i++){
int x=nums[i];
position[x].push_back(i);
}
for(auto &pos:position){
int left=0;
for(int right=0;right<pos.size();right++){
while(pos[right]-pos[left]-(right-left)>k){
left++;
}
res=res<right-left+1?right-left+1:res;
}
}
return res;
}
};
滑动窗口:定长
class Solution {
public:
int longestEqualSubarray(vector<int>& nums, int k) {
int n=nums.size();int res=1;int sum=0;
for(int i=0;i<n;i++){//右边扩展
sum+=nums[i];
if(i<k-1) continue;//到达定长
sum-=nums[i-k+1];//左边收缩
res=res<sum?sum:res;//更改状态
}
}
return res;
}
};
滑动窗口:不定长
class Solution {
public:
int longestEqualSubarray(vector<int>& nums, int k) {
int n=nums.size();int res=1;
for(int right=0;right<pos.size();right++){
while(限制条件,与left有关){
left++;
}
res=res<right-left+1?right-left+1:res;//求出极值
}
}
return res;
}
};