题目链接:2831.找出最长等值子数组
> 将元素值为下标索引,将元素在数组nums中的出现位置记录在二维数组position中,position每个下标对应的数组都是下标索引在nums中的出现位置
> 记position的下标为index,index在nums中的出现次数为position[index].size(),记作cnt1,而在nums数组中index第一次出现到最后一次出现,这个范围内nums的元素个数为:position[index][position[index].size() - 1] - position[index][0] + 1,记作cnt2,那么cnt2 - cnt1就等于需要删除的元素的个数,删除之后最长等值数组的长度就等于滑动窗口的right - left + 1
cpp实现:
cpp
class Solution {
public:
int longestEqualSubarray(vector<int>& nums, int k) {
int ans = 0; // 初始化长度为0
vector<vector<int>> position(nums.size() + 1); //定义nums中元素出现的下标数组
for (int i = 0; i < nums.size(); i++) {
position[nums[i]].push_back(i);
}
for (auto& e : position) { //分别遍历每一个元素所对应的下标
int left = 0; //滑动窗口初始化左端点为0
for (int right = 0; right < e.size(); right++) { //不断移动右端点
while (e[right] - e[left] + 1 - (right - left + 1) > k) { //当需要移除的元素个数大于k时
left += 1; //收缩窗口
}
ans = max(ans, right - left + 1); //退出循环之后,说明满足条件,更新ans
}
}
return ans;
}
};
python3实现:
python
class Solution:
def longestEqualSubarray(self, nums: List[int], k: int) -> int:
ans = 0
position = [[] for _ in range(len(nums) + 1)]
for i, x in enumerate(nums):
position[x].append(i)
for e in position:
left = 0
for right in range(len(e)):
while e[right] - e[left] + 1 - (right - left + 1) > k:
left += 1
ans = max(ans, right - left + 1)
return ans