单独的数| 豆包MarsCode AI 刷题

75 阅读3分钟

问题描述

在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。
要求:

  1. 设计一个算法,使其时间复杂度为 O(n),其中 n 是班级的人数。
  2. 尽量减少额外空间的使用,以体现你的算法优化能力。

测试样例

样例1:

输入:cards = [1, 1, 2, 2, 3, 3, 4, 5, 5]
输出:4
解释:拿到数字 4 的同学是唯一一个没有配对的。

样例2:

输入:cards = [0, 1, 0, 1, 2]
输出:2
解释:数字 2 只出现一次,是独特的卡片。

样例3:

输入:cards = [7, 3, 3, 7, 10]
输出:10
解释:10 是班级中唯一一个不重复的数字卡片。

约束条件

  • 1 ≤ cards.length ≤ 1001
  • 0 ≤ cards[i] ≤ 1000
  • 班级人数为奇数
  • 除了一个数字卡片只出现一次外,其余每个数字卡片都恰好出现两次

问题分析

这道题说的是在一堆成对出现的数中找出唯一的单独的数。是一道非常简单的题,这里给大家提供两种思路。

方法一:哈希表

这是一种非常直接的方法,直接用哈希表记录每个数字出现的次数然后找出出现次数为1的数字就可以了。这个表中key是具体的数字,value是每个数字出现的次数。下面是详细步骤:

1.初始化哈希表

先创建一个哈希表用来存储每个数字和每个数字出现的次数。

2.遍历这个数组并且更新哈希表

遍历这个数组,对于每个数字,如果它不在哈希表中则将它添加到表中,并且将其出现次数设置为1。 如果已经存在表中,就将其出现次数加1。

3.找出单独的数

再次遍历哈希表,找到value为1的数字,这个数就是单独的数。

代码示例
int solution(std::vector<int> cards) {
    std::unordered_map<int, int> countMap;

    // 遍历所有数字,更新哈希表中对应数字的计数
    for (int num : cards) {
        countMap[num]++;
    }

    // 遍历哈希表,找到出现次数为1的数字
    for (const auto& pair : countMap) {
        if (pair.second == 1) {
            return pair.first;
        }
    }

    return -1; // 如果没有找到,返回-1

方法二:异或

第二种方法更加简单且高效,我们可以使用异或^来找到单独的数。如果大家忘了什么是异或,下面我来给大家简单介绍一下异或的特点。
异或的运算规则是相同为0,不同为1,即\

1 ^ 1 = 0
0 ^ 0 = 0
1 ^ 0 = 1

异或性质

交换律: A ^ B = B ^ A
结合律: ( A ^ B ) ^ C = A ^ ( B ^ C )
自反性: A ^ B ^ B = A (由结合律可推: A ^ B ^ B = A ^ ( B ^ B ) = A ^ 0 = A)

根据异或的特性,我们只需要将数组遍历,遇到相同的数时变为0,遇到单独数字时变成该数字,最后仅剩下单独数字。是不是非常巧妙呢。

代码示例
int solution(std::vector<int> inp) {
    int result = 0;
    for (int i=0; i < inp.size(); i++) 
    {
        result ^= inp[i];
    }
    return result;
}