uva 11572 - Unique Snowflakes(两种解法)

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

猜你喜欢

转载自blog.csdn.net/qiang_____0712/article/details/84932205