专栏文章

题解:AT_abc395_c [ABC395C] Shortest Duplicate Subarray

AT_abc395_c题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miq3aoww
此快照首次捕获于
2025/12/03 22:15
3 个月前
此快照最后确认于
2025/12/03 22:15
3 个月前
查看原文
比都比了,就写一发吧。

思路

双指针~~
这题很像双指针,所以用双指针
观察题目,可以发现:当一个以 ll 为开头的有重复值的最短连续子序列的结尾为 rr,则以 l+1l+1 为开头的有重复值的最短连续子序列的结尾至少为 rr。由此很容易看出此题可以用双指针。
我们从 11nn 枚举所有 ll,对于每个 ll,寻找以 ll 为开头的有重复值的最短连续子序列的结尾 rr,并将所有序列的长度取最小值输出。如果不存在以 ll 为开头的有重复值的连续子序列,就不参与取最小值。
具体细节看代码吧!

代码

CPP
#include<bits/stdc++.h>
#define ll long long
#define pp pair<int,int>
using namespace std;
int n,ans,a[2000005],b[2000005];//b数组标记每个数是否出现过 
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n;
	ans=n+1;//ans设最大值 
	for(int i=1;i<=n;++i)cin>>a[i];
	for(int l=1,r=2;l<=n;++l){
		b[a[l]]=1;//标记a[l]这个数 
		while(!b[a[r]]&&r<=n||r<=l){
			b[a[r]]=1;//标记a[r] 
			++r;
		}
		//寻找以l为开头的有重复值的最短连续子序列的结尾r
		if(b[a[r]])ans=min(r-l+1,ans);
		//如果存在以l为开头的有重复值的最短连续子序列,就取最小值 
		b[a[l]]=0;//去掉a[l]这个数 
	}
	if(ans==n+1)cout<<-1<<"\n";
	//如果不存在有重复值的连续子序列,输出-1 
	else cout<<ans<<"\n";
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...