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;
}