唯一的雪花 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;
}

猜你喜欢

转载自blog.csdn.net/FireflyNo1/article/details/82966273