唯一最小数
【题目描述】
给定一个长度为n的整数数数组 a1,a2,…,an。
请你找到数组中只出现过一次的数当中最小的那个数。
输出找到的数的索引编号。
数组的中的索引下标从1开始。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。
每组数据第一行包含整数 n。
第二行包含 n个整数 a1,a2,…,an。
输出格式
每组数据输出一行结果,即满足条件的数的索引编号,如果不存在满足条件的数,则输出 −1。
数据范围
1 ≤ T ≤ 2×104,
1 ≤ n ≤ 2×105,
1 ≤ ai ≤ n,
同一测试点内的所有 n 的和不超过 2×105。
【解题思路】
使用哈希表,其中key表示原数组中的元素,value表示该元素出现的次数。这样遍历一遍数组就将数组中的所有的元素进行了统计。
之后只需要查找哈希表中value为1的记录,然后找出所有value为1中的最小元素的下标。
时间复杂度
数组的长度为n,哈希表的插入和查询为O(1),整个算法过程中主要对原始数组进行两次遍历,所以最终的时间复杂度为O(N)。
【代码示例】
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int n;
int w[N], cnt[N]; // w[N]用来存储数组中的元素,cnt[N]用来存储w[N]数组中元素出现的次数
int main()
{
int T;
scanf("%d", &T);
while (T --)
{
scanf("%d", &n);
memset(cnt, 0, (n + 1) * 4); // 讲cnt数组中的元素置为0
// 统计w[N]数组中元素的个数
for (int i = 0; i < n; i++)
{
scanf("%d", &w[i]);
cnt[w[i]] ++;
}
int res = -1; // 存储数组中元素个数为1的最小元素的下标
// 在哈希表中查找w[N]中出现次数为1的元素,并找出其中最小数的下标
for (int i = 0; i < n; i++)
{
if (cnt[w[i]] == 1)
{
if (res == -1 || w[res] > w[i]) // 找出元素个数为1的最小的元素
res = i;
}
}
if (res != -1) res ++; // 保证最终下标从1开始
printf("%d\n", res);
}
}