给定一个数组arr,和一个整数k
你可以随意删除arr中的数字,最多删除k个
目的是让连续出现一种数字的长度尽量长
返回这个尽量长的长度
比如数组arr = {3,-2,3,3,5,6,3,-2}, k = 3
你可以删掉-2、5、6(最多3个),这样数组arr = {3,3,3,3,-2}
可以看到连续出现3的长度为4
这是所有删除方法里的最长结果,所以返回4
1 <= arr长度 <= 3 * 10^5
-10^9 <= arr中的数值 <= 10^9
0 <= k <= 3 * 10^5
思路:
遍历数组arr,以当前位置i为结尾的子数组,删除不超出k个数,组成的最大长度的连续子数组,所有这些子数组中的最大长度即为答案。每个arr[i]维护一个由下标组成的窗口,窗口内的值就是以arr[i]为结尾,删除不超过k个数后的子数组中,所有等于arr[i]的数的下标. 窗口的长度即是当前位置为结尾的子数组删除不超过k个数后,组成的最大长度的连续子数组。以下代码由c++实现。
代码:
int longest(vector<int> &arr, int k) {
unordered_map<int, list<int>> indexList;
int ans = 0;
for(int i = 0;i < arr.size();i++) {
if (indexList.find(arr[i]) == indexList.end()) {
indexList.insert(make_pair(arr[i], list<int>()));
}
list<int> indexes = indexList.at(arr[i]);
indexList.erase(arr[i]);
while (indexes.empty() == false && i - indexes.front() - indexes.size() > k) {
indexes.pop_front();
}
indexes.push_back(i);
indexList.insert(make_pair(arr[i], indexes));
int cur = (int)indexes.size();
ans = max(ans,cur);
}
return ans;
}