唯一的雪花 uva 11572 (滑動視窗)
阿新 • • 發佈:2018-12-14
紫書 第八章
輸入一個長度為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; }