问题描述
在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。除了一个数字之外,所有的数字都恰好出现了两次。需要找到那个拿了独特数字卡片的同学手上的数字是什么。
要求
设计一个算法,使其时间复杂度为 O(n),其中 n 是班级的人数。尽量减少额外空间的使用。
测试样例
样例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 班级人数为奇数 除了一个数字卡片只出现一次外,其余每个数字卡片都恰好出现两次
解题思路
这个问题可以通过使用异或运算来解决。异或运算的性质是:任何数和 0 异或等于它本身,任何数和它本身异或等于 0。因此,如果一个数字出现两次,那么它和它自己异或的结果是 0。而唯一出现一次的数字,它和 0 异或的结果是它本身。所以,我们可以通过将所有数字进行异或运算,最终得到的结果就是那个只出现一次的数字。
算法步骤
- 初始化一个变量
unique为 0。 - 遍历数组
cards中的每个元素。 - 将
unique与当前元素进行异或运算,并将结果赋值给unique。 - 遍历结束后,
unique的值就是那个只出现一次的数字。
它实现了之前讨论的算法,用于找出数组中唯一一个出现一次的数字。代码中的 solution 函数接受一个整数类型的 vector 作为参数,并返回一个整数,即那个只出现一次的数字。
在 main 函数中,你添加了三个测试用例,并使用 std::cout 来输出测试结果。每个测试用例都会调用 solution 函数,并检查返回值是否与预期的输出相等。如果相等,std::cout 会输出 1,表示测试通过;如果不相等,会输出 0,表示测试失败。
这段代码可以直接在支持 C++ 的编译器中编译和运行。如果你想要看到更直观的测试结果,可以将 std::cout 的输出改为直接打印返回值和预期值,例如:
#include <iostream>
#include <vector>
int solution(std::vector<int> cards) {
int result = 0; // 初始化结果为0
for (int card : cards) {
result ^= card; // 对每个元素进行异或运算
}
return result; // 返回最终结果
}
int main() {
// 添加你的测试用例
std::cout << "Test 1: " << (solution({1, 1, 2, 2, 3, 3, 4, 5, 5}) == 4 ? "Passed" : "Failed") << std::endl;
std::cout << "Test 2: " << (solution({0, 1, 0, 1, 2}) == 2 ? "Passed" : "Failed") << std::endl;
std::cout << "Test 3: " << (solution({7, 3, 3, 7, 10}) == 10 ? "Passed" : "Failed") << std::endl;
return 0;
}
在 solution 函数中,我们初始化了一个变量 result 为 0,然后遍历 cards 中的每个元素。对于每个元素,我们使用异或运算符 ^= 将其与 result 进行异或操作,并将结果存储回 result。由于异或操作的性质,所有成对出现的数字都会被抵消,只剩下那个只出现一次的数字。
在 main 函数中,我们添加了三个测试用例来验证 solution 函数的正确性。每个测试用例都调用 solution 函数,并检查返回值是否与预期的输出相等。如果相等,输出 1 表示测试通过;如果不相等,输出 0 表示测试失败。