题意:
题目给出一段长度为n的序列我们要在这一段序列中随便找出一段子序列使得这一段子序列中的不同的值有k个,同时我们要保证其最长,我们最后输出时如果最长的子序列不唯一可以随意输出。
思路:
处理这种子序列问题我们要用的就是双指针法,我们先定义左右指针,从1开始右指针依次向右移动在这移动过程中我们设置一个类似于map的东西用来记录序列的每一个值出现过几次,当前遍历的值如果在之前出现零次的话我们就使得sum这个值++,sum这个值是用来储存该子序列中不同值的个数。如下图所示;
如果我们发现sum的值大于了k值我们就移动左指针,将不同的值减去;如下图所示。
在过程中我们还有一步关键操作。
if(zright-zleft>right-left)//我们要把最大边界保存下来
{
right=i;
left=index;
}
最后我们最大边界即可。
#include<bits/stdc++.h>
using namespace std;
const int INX=3e6;
int a[INX],finds[INX];
int main()
{
int num1,num2;
cin>>num1>>num2;
int left=1,right=1;
int sum=0;
int index=1;
for(int i=1;i<=num1;i++)
{
cin>>a[i];
if(finds[a[i]]==0)
{
sum++;
}
finds[a[i]]++;
while(sum>num2)
{
finds[a[index]]--;
if(finds[a[index]]==0)
{
sum--;
}
index++;
}
if(i-index>right-left)
{
right=i;
left=index;
}
}
cout<<left<<" "<<right;
}