UVA - 11572 Unique Snowflakes(唯一的雪花) : 滑動窗口


題目點此跳轉

思路

 題目意思是輸入一個長度為n(n≤106)的序列A,找到一個盡量長的連續子序列 ALAR ,使得該序列中沒有相同的元素。

 首先定義L和R表示要找的結果的左右端點,一開始L = R = 0;
 然后我們不斷地增加R,直到不能增加了為止,不能增加是因為再增加的話就有相同的元素了;
 這個時候我們維護一下最大值,然后開始增加L,直到將那個使R不能再增加的元素去掉為止;
 接着我們就又能繼續增加R了,直到R到序列尾。

 我們會有一個直觀的感覺, 這里的[L, R] 就像一個窗口一樣, 一開始在最左邊,然后不斷地向右邊滑動, 而且不會滑回來,因為R是不斷增加的,L也是不斷增加的。這大概就是滑動數組了吧。

 還有一點,我們可以用map來預處理出每一位元素上一次出現的位置, 這樣L往后跳的時候就不用一位一位地找了。

代碼

#include <algorithm>
#include <iostream>
#include <sstream>
#include <utility>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <cstring>
#include <cstdio>
#include <cmath>
#define met(a,b) memset(a, b, sizeof(a));
#define IN freopen("in.txt", "r", stdin);
#define OT freopen("out.txt", "w", stdout);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 1e6 + 100;
const int INF = 0x7fffffff;
const int dir[5][2] = {0,0,-1,0,1,0,0,-1,0,1};
const LL MOD = 1e9 + 7;

int n, a[maxn];
int pre[maxn];
map<int, int> m;

int main() {
#ifdef _LOCAL
IN; //OT;
#endif // _LOCAL

int t; cin >> t;
while(t--) {
scanf("%d", &n); m.clear();
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for(int i = 1; i <= n; ++i) {
if(!m.count(a[i])) pre[i] = -1;
else pre[i] = m[a[i]];
m[a[i]] = i;
}
int L = 1, R = 1, ans = 0;
while(R <= n) {
while(R+1 <= n && pre[R+1] < L) ++R;
ans = max(ans, R-L+1); ++R;
if(R > n) break;
L = pre[R]+1;
}
printf("%d\n", ans);
}

return 0;
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: