题目描述
给定一个长度为n的整数序列,请找出最长的不包含重复数字的连续子序列,输出它的长度。
算法1
(枚举) $O(n)$
滑动窗口 记录窗口的起始点 l r
同时使用一个数组或者map记录该窗口区间各个数字出现的次数(后来证明使用map会超时)
vector[HTML_REMOVED] v(N,0);
如果r增加的时候 添加的元素在区间已经有了 那么就从窗口起点开始逐个弹出 直到将重复的元素弹出
这样r就可以添加滑动窗口区间了
if (m[v[r]] ) {
//说明r中的元素 已经在滑动窗口区间出现了 那么需要将区间里的元素弹出
while (v[l] != v[r]) {
if(m[v[l]]) m[v[l]]--;
l++;
}
if (m[v[l]] )m[v[l]]--;
l++;
}
每次添加成功 记录窗口的长度值 和答案比较 答案取值其中最大的值
ans = max(ans, r - l + 1);
C++ 代码
#include <iostream>
#include <set>
#include <map>
#include <vector>
using namespace std;
const int N = 1000010;
vector<int> v(N,0);
int t;
int n;
int ans = -1;
vector<int> m(N,0);
int main()
{
cin >> t;
for(int i = 1;i<=t;i++){
cin >> v[i];
}
int l = 1; int r = l+1;
m[v[l]]++;
while (l <= r && l <= t && r <= t) {
if (m[v[r]] ) {
//说明r中的元素 已经在滑动窗口区间出现了 那么需要将区间里的元素弹出
while (v[l] != v[r]) {
if(m[v[l]]) m[v[l]]--;
l++;
}
if (m[v[l]] ) m[v[l]]--;
l++;
}
//r索引元素进入滑动窗口
m[v[r]]++;
ans = max(ans, r - l + 1);
//下一轮比对
r++;
}
cout << ans << endl;
return 0;
}
map没超时啊
acwing799. 最长连续不重复子序列
比较尴尬,显示ac,但是跑了1016ms。
可能调节了测试时间
原来答案是1000ms左右 现在跑360ms
原来tle的答案 可能现在就1000多ms了