1. 程式人生 > >唯一的雪花 uva 11572 (滑動視窗)

唯一的雪花 uva 11572 (滑動視窗)

紫書 第八章

輸入一個長度為n的序列A,找到一個儘量長的連續子序列al-ar,使得該序列中沒有相同元素。

設左端點為  L,右端點為R ,初始L = 0,  R=0,R不斷增加,只要在L和R中間沒有出現過重複的數就一直增加。

O(nlogn)

程式碼如下:  

#include <iostream>
#include <set>
#include <algorithm>

using namespace std;
const int maxn = 100000 + 5;

int t, a[maxn], n;
int main(){
	cin >> t;
	while(t--){
		cin >> n;
		for(int i = 0; i < n; i++)  cin >> a[i];
		int l = 0, r = 0, ans = 0;
		while(r<n){
			set<int> s;                 //set來看看有沒有重複數字 
			while(r < n && !s.count(a[r])) s.insert(a[r++]);
			ans = max(ans, r - l);
			s.erase(a[l++]);
		}
		cout << ans << endl;
	}
	return 0;
} 

還可以用一個map求出last【i】,即下標i的“上一個元素的下標”。

程式碼如下:  

#include <iostream>
#include <map>
using namespace std;
const int maxn = 100000 + 5;
int n, t;
map<int, int> cur;

int a[maxn], last[maxn];
int main() {
	cin >> t;
	while(t--) {
		cur.clear();
		cin >> n;
		for(int i = 0; i < n; ++i) {
			cin >> a[i];
			if(!cur.count(a[i]))  last[i] = -1;
			else last[i] = cur[a[i]];
			cur[a[i]] = i;
		}
		int l = 0, r = 0, ans = 0;
		while(r < n) {
			while(r < n && last[r] < l) r++;   //如果上一個元素小於L,即不在區間中,那麼r就可以加 
			ans = max(ans, r - l);
			l++;            //r加完以後  就左邊開始加,加到右邊 也可以加為止 
		}
		cout << ans <<endl;       //最後一個輸出 
	}
	return 0;
}