题解:学而思编程 唯一最小数

【题目来源】

学而思编程:唯一最小数

【题目描述】

给定一个长度为 \(n\) 的整数数组 \(a_1,a_2,\dots ,a_n\)

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

输出找到的数的索引编号

\(a_1\) 的索引编号为 \(1\)\(a_2\) 的索引编号为 \(2\),…,\(a_n\) 的索引编号为 \(n\)

【输入】

第一行包含整数 \(T\),表示共有 \(T\) 组测试数据。

每组数据第一行包含整数 \(n\)

第二行包含 \(n\) 个整数 \(a_1,a_2,\dots ,a_n\)

【输出】

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

【输入样例】

2
2
1 1
3
2 1 3

【输出样例】

-1
2

【核心思想】

  1. 问题分析:给定长度为 \(n\) 的数组 \(a_1, a_2, \ldots, a_n\),找出只出现过一次的数中最小的那个数的索引。这是一个频次统计 + 线性扫描问题,关键在于先统计每个数字的出现次数,再遍历找满足条件的最小值。

  2. 算法选择

    • 频次统计:用数组 cnt 记录每个数字出现的次数
    • 线性扫描找最小:遍历数组,在出现次数为 \(1\) 的数字中找最小值,记录其索引
  3. 关键步骤

    • 初始化:读取 \(T\)(测试组数)
    • 处理每组数据
      • 读取 \(n\) 和数组 \(a[1..n]\)
      • memset(cnt, 0, sizeof(cnt)):重置计数数组
      • 统计频次:遍历 \(i\)\(1\)\(n\)cnt[a[i]]++
      • 寻找唯一最小数
        • ans = -1
        • 遍历 \(i\)\(1\)\(n\)
          • cnt[a[i]] == 1(只出现一次):
            • ans == -1a[ans] > a[i]ans = i(更新为更小值的索引)
      • 输出 ans
  4. 时间/空间复杂度

    • 时间复杂度:\(O(T \times n)\),每组数据两次线性遍历
    • 空间复杂度:\(O(V)\)\(V\) 为值域大小,计数数组 cnt
  5. 频次统计的核心思想

    • 两次扫描策略:第一次扫描统计频次,第二次扫描找目标值。分离统计与查询,避免边统计边判断时的信息不完整
    • 最小值维护ans 初始为 \(-1\) 表示未找到,找到第一个唯一值后,后续只需比较数值大小更新索引
    • 值域限制:题目隐含值域不大(cnt 数组直接开 \(2 \times 10^5 + 10\)),可用数组计数;若值域大可用 map
    • 索引优先:题目要求输出索引而非数值,因此 ans 存储索引,比较时用 a[ans] 取对应数值
    • 适用于"频次约束下的极值查找"类问题,频次统计将重复判断优化为 \(O(1)\) 查询

【算法标签】

模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;

int a[N], cnt[N];

int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        int n;
        cin >> n;
        memset(cnt, 0, sizeof(cnt));  // 重置计数数组
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
            cnt[a[i]]++;  // 统计每个数字出现的次数
        }
        int ans = -1;
        for (int i = 1; i <= n; i++)
        {
            // 寻找只出现一次的数字
            if (cnt[a[i]] == 1)
            {
                // 更新答案为最小值的索引
                if (ans == -1 || a[ans] > a[i])
                {
                    ans = i;
                }
            }
        }
        cout << ans << endl;  // 输出索引,如果不存在则输出-1
    }
    return 0;
}

【运行结果】

2
2
1 1
-1
3
2 1 3
2
posted @ 2026-07-05 14:17  团爸讲算法  阅读(3)  评论(0)    收藏  举报