专栏文章
题解: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 个月前
比都比了,就写一发吧。
思路
双指针~~
这题很像双指针,所以用双指针
观察题目,可以发现:当一个以 为开头的有重复值的最短连续子序列的结尾为 ,则以 为开头的有重复值的最短连续子序列的结尾至少为 。由此很容易看出此题可以用双指针。
我们从 至 枚举所有 ,对于每个 ,寻找以 为开头的有重复值的最短连续子序列的结尾 ,并将所有序列的长度取最小值输出。如果不存在以 为开头的有重复值的连续子序列,就不参与取最小值。
具体细节看代码吧!
观察题目,可以发现:当一个以 为开头的有重复值的最短连续子序列的结尾为 ,则以 为开头的有重复值的最短连续子序列的结尾至少为 。由此很容易看出此题可以用双指针。
我们从 至 枚举所有 ,对于每个 ,寻找以 为开头的有重复值的最短连续子序列的结尾 ,并将所有序列的长度取最小值输出。如果不存在以 为开头的有重复值的连续子序列,就不参与取最小值。
具体细节看代码吧!
代码
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 条评论,欢迎与作者交流。
正在加载评论...