CF1714B题解

题目链接

我的翻译

题目描述

t t t 组数据( 1 ≤ t ≤ 1 0 4 1\le t\le10^4 1t104)。

每组数据,给定 n n n 1 ≤ n ≤ 2 ⋅ 1 0 5 1\le n\le2\cdot10^5 1n2105)和序列 a = [ a 1 , a 2 , … , a n ] a=[a_1,a_2,\dots,a_n] a=[a1,a2,,an] 1 ≤ a i ≤ n 1\le a_i\le n 1ain),需要删除 a a a的一个前缀,使剩下的数不重复。

找出要删除的最小前缀,输出它的长度。

样例解释

删除最小前缀后,剩下的序列分别是:

  • [ 1 , 4 , 3 ] [1,4,3] [1,4,3]

  • [ 1 ] [1] [1]

  • [ 1 ] [1] [1]

  • [ 6 , 5 , 4 , 3 , 2 , 1 ] [6,5,4,3,2,1] [6,5,4,3,2,1]

  • [ 2 , 1 ] [2,1] [2,1]

所有剩下的序列只包含不同的元素。


解法

对于每个序列,只需要找出从后往前第一个与之后的数字重复的数字的下标即可。不存在这个数字输出 0 0 0

考虑使用STL中的set容器,从后往前遍历每个序列元素,若不在set中则加入set,若已经存在,下标就是答案。可设置一个虚拟元素 a 0 = a 1 a_0=a_1 a0=a1 ,遍历从 n n n 0 0 0 ,若 [ a 1 , a 2 , … , a n ] [a_1,a_2,\dots,a_n] [a1,a2,,an] 中无重复数字, 0 0 0 就是答案。

核心代码:

int t,n,a[200001];
set<int>st;

scanf("%d",&t);
while(t--)
{
	scanf("%d",&n);
	st.clear();					//使用前清空容器
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	a[0]=a[1];					//虚拟元素
	for(int i=n;i>=0;i--)		//遍历
		if(st.count(a[i]))		//判断当前元素是否与已进入容器的元素重复
		{
			cout<<i<<'\n';		//重复,下标即为答案
			break;
		}
		else
			st.insert(a[i]);	//不重复,加入容器
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值