题目解析:找单独的数

115 阅读2分钟

问题描述


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

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

解题思路

思路一:第一反应是使用unordered_map,既能统计数量,占用空间也比数组小。

先问一下MarsCode AI unordered_map的基本使用方法 unordered_map 是 C++ 标准库中的一个关联容器,用于存储键值对。它基于哈希表实现,提供了快速的查找、插入和删除操作。下面是 unordered_map 的基本使用方法:

1. 包含头文件

首先,你需要包含 unordered_map 的头文件:

#include <unordered_map>

2. 声明和初始化

你可以声明一个 unordered_map,并指定键和值的类型:

std::unordered_map<int, 

std::string> myMap;

3. 访问元素

你可以使用 [] 运算符或 at 方法来访问元素:

std::string value1 = myMap

[1];  // 访问键为1的元素

std::string value2 = myMap.

at(2);  // 访问键为2的元素

4. 遍历元素

你可以使用范围for循环或迭代器来遍历 unordered_map

for (const auto& pair : 

myMap) {

    std::cout << "Key: " << 

    pair.first << ", Value: 

    " << pair.second << 

    std::endl;

} 这样我们就知道可以使用unordered_map遍历数组,记录每个数字出现的次数,然后用第二次遍历找出只出现一次的数字。就像下面这样

int res=0;
    std::unordered_map<int, int>f;
    for(int i:cards){
         f[i]++;
    }
    for(int i:cards){
        if(f[i]==1) res=i;
    }

思路二:为了尽量减少额外空间的使用,可以考虑使用位运算来解决这个问题。之前位运算用的很少,根本就没想到这方面,可以看到我们的豆包AI助手还是非常强大的。

算法步骤

  1. 异或运算的性质:异或运算(XOR)有一个非常有用的性质:

    • a ^ a = 0 (任何数与自己异或结果为0)
    • a ^ 0 = a (任何数与0异或结果为它本身)
    • 异或运算满足交换律和结合律,即 a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b
  2. 利用异或运算:我们可以遍历整个数组,对所有元素进行异或运算。由于相同的数字异或结果为0,最终剩下的就是那个唯一出现一次的数字。 这样只使用一次遍历即可得到答案,代码如下

int res=0;
    for(int i:cards){
        res^=i;
    }