唯一最小数

116 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情

题目描述

给定一个长度为 nn 的整数数组 a1,a2,…,ana1,a2,…,an。

请你找到数组中只出现过一次的数当中最小的那个数。

输出找到的数的索引编号

a1a1 的索引编号为 11,a2a2 的索引编号为 22,…,anan 的索引编号为 nn。

输入格式

第一行包含整数 TT,表示共有 TT 组测试数据。

每组数据第一行包含整数 nn。

第二行包含 nn 个整数 a1,a2,…,ana1,a2,…,an。

输出格式

每组数据输出一行结果,即满足条件的数的索引编号,如果不存在满足条件的数,则输出 −1−1。

数据范围

1≤T≤2×1041≤T≤2×104, 1≤n≤2×1051≤n≤2×105, 1≤ai≤n1≤ai≤n, 同一测试点内的所有 nn 的和不超过 2×1052×105。

输入样例:

6
2
1 1
3
2 1 3
4
2 2 2 3
1
1
5
2 3 2 4 2
6
1 1 5 5 4 4

输出样例:

-1
2
4
1
2
-1

思路

看了数据范围,我们会发现ai的大小非常小,只有2*10^5. 我才不会告诉你们我只会暴力

所以我们会很容易想到用cnt[i]数组来表示这个数列中i出现的个数 枚举每个数,当且仅当cnt[a[i]]==1且a[i]<a[前i减1个数满足条件的下标]时,更新即可 时间复杂度 O(n)O(n) 话不多说,上代码!!!! 没看懂的可以看一下代码的注释

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+10;
int t,n,a[N],cnt[N];//cnt数组表示i这个数字在数列里出现的次数
int main(){
    cin>>t;//读入数据数
    while(t--){
        scanf("%d",&n);//读入数列中元素个数
        memset(cnt,0,sizeof cnt);//记得将cnt数组初始化为0
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            cnt[a[i]]++;//a[i]这个数又出现了一次
        }
        int res=-1;//记录最后答案,如果没更新过就输出res,所以将res初始化为-1
        for(int i=1;i<=n;i++){//依次枚举每一个元素
            if(cnt[a[i]]==1){//如果只出现了一次
                if(res==-1||a[res]>a[i]) res=i;//当且仅当res没被更新过或者这个答案更优,更新答案
            }
        }
        printf("%d\n",res);//输出答案
    }
    return 0;
}

\