https://vjudge.net/problem/UVA-11572
题意:给出 n个数,找到尽量长的一个序列,使得该序列中没有重复的元素
思路:对于该类段查找问题可以采用经典的滑动窗口方法,即维护一个窗口,窗口的左右边界用两个变量L,R代表,先增加R直到出现重复数字,再增加L,再增加R,直到R达到n
滑动窗口 求解;
当右端碰到有相同的数的时候,左端向右滑动一位数
思路1,set判别重复。
#include <cstdio>
#include <cmath>
#include <vector>
#include <set>
#include <stack>
#include <sstream>
#include <algorithm>
#include <iostream>
using namespace std;
int main() {
int n,t,temp;
cin>>t;
vector<int> vs;
set<int> iset;
while(t--)
{
cin>>n;
int index=n;
vs.clear();
iset.clear();
while(index--)
{
cin>>temp;
vs.push_back(temp);
}
int L=0,R=0,imax=0;
for(int R=0;R<n;R++)
{
while(iset.count(vs[R]))
{
iset.erase(vs[L]);
L++;
}
iset.insert(vs[R]);
imax=max(imax,(int)iset.size());
}
cout<<imax<<endl;
}
return 0;
}
解法2,使用pair记录上次该数据出现的坐标。如果将要加入的数字的PRE值2在LR中没有出现,就可以加入,否则,需要将L后移
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <sstream>
#include <algorithm>
#include <iostream>
using namespace std;
int main() {
int n,t,temp;
cin>>t;
vector<int> vs,pre;
map<int,int> imap;
while(t--) {
cin>>n;
int index=0;
vs.clear();
imap.clear();
pre.resize(n);
while(index<n) {
cin>>temp;
vs.push_back(temp);
if(!imap.count(temp))
pre[index]=-1;
else
pre[index]=imap[temp];
imap[temp]=index;
index++;
}
//for(int i=0;i<n;i++) cout<<pre[i]<<" ";
//cout<<endl;
int L=0,R=0,imax=0;
for(R=0; R<n; R++) {
temp=pre[R];
if(temp<L) {
} else L=temp+1;
imax=max(imax,R-L+1);
}
cout<<imax<<endl;
}
return 0;
}