只出现一次的数字
详细说明:给定一个整数数组,其中除了一个整数只出现一次外,其余所有数字都恰好出现两次。找到那个不重复的整数。
最坏的情况下的时间复杂度:O(n)
空间复杂度:O(1)
这个程序用于找出数组中唯一一个不重复的整数,利用异或运算的特性高效实现。以下是分块解释:
-
头文件引入:
-
<cassert>
用于断言测试。 -
<iostream>
用于输入输出操作。 -
<vector>
用于存储整数数组。
-
-
命名空间:
-
使用嵌套命名空间
bit_manipulation::find_non_repeating_integer
组织代码,提高模块化。
-
-
核心函数:
int64_t find_non_repeating_integer(const std::vector<int>& nums) {
int _xor = 0;
for (const int& num : nums) {
_xor ^= num;
}
std::cout << _xor << std::endl;
return _xor;
}
-
功能:通过异或运算找出数组中唯一出现一次的数字。
-
原理:利用异或运算的以下性质:
-
a ^ a = 0
(相同数异或结果为0)。 -
0 ^ b = b
(任何数与0异或结果为其本身)。
-
二进制异或操作
异或操作是逐位进行的逻辑运算,我们先看几个简单的二进制异或的例子:
-
0 XOR 0 = 0:二进制位相同,结果为0。
-
0 XOR 1 = 1:二进制位不同,结果为1。
-
1 XOR 0 = 1:二进制位不同,结果为1。
-
1 XOR 1 = 0:二进制位相同,结果为0。
将数字转换为二进制并进行异或
我们用具体的数字来说明异或的过程:
-
数字1和1异或:
-
二进制表示:1 (01) 和 1 (01)
-
异或结果:00(0)
-
-
数字1和2异或:
-
二进制表示:1 (01) 和 2 (10)
-
异或结果:11(3)
-
在代码中的应用
现在,我们来看代码中的异或操作是如何实现的:
-
初始化一个变量
_xor
为0。 -
遍历数组中的每个元素,并将每个元素与
_xor
进行异或操作。 -
重复的元素在异或时会相互抵消,最终剩下的就是唯一的不重复元素。
我们以第一个测试用例nums_one = {1, 1, 2, 2, 4, 5, 5}
为例,逐步模拟异或操作的过程:
-
初始化
_xor = 0
-
遍历数组中的每个元素:
-
_xor ^= 1
→_xor
变为1(二进制:01) -
_xor ^= 1
→_xor
变为0(二进制:00) -
_xor ^= 2
→_xor
变为2(二进制:10) -
_xor ^= 2
→_xor
变为0(二进制:00) -
_xor ^= 4
→_xor
变为4(二进制:100) -
_xor ^= 5
→_xor
变为1(二进制:001) -
_xor ^= 5
→_xor
变为4(二进制:100)
-
最终,_xor
的值为4,这正是数组中唯一的不重复元素。其他测试用例的异或过程也是类似的,通过异或操作,所有重复的元素都被抵消,剩下的就是唯一的不重复元素。
-
步骤:
-
初始化
_xor
为0。 -
遍历数组,将所有元素依次与
_xor
异或。 -
最终
_xor
的值即为唯一不重复的数。
-
4.测试函数:
static void test() {
std::vector<int> nums_one{1, 1, 2, 2, 4, 5, 5};
std::vector<int> nums_two{203, 3434, 4545, 3434, 4545};
std::vector<int> nums_three{90, 1, 3, 90, 3};
assert(find_non_repeating_integer(nums_one) == 4); // 测试用例1
assert(find_non_repeating_integer(nums_two) == 203); // 测试用例2
assert(find_non_repeating_integer(nums_three) == 1); // 测试用例3
std::cout << "All test cases passed!" << std::endl;
}
-
验证函数在不同输入场景下的正确性。
-
测试用例:
-
nums_one
中4
是唯一不重复数。 -
nums_two
中203
是唯一不重复数。 -
nums_three
中1
是唯一不重复数。
-
总结:程序通过异或运算高效找到数组中唯一出现一次的数字,时间复杂度为 O(n),空间复杂度为 O(1)。测试用例覆盖了不同场景,确保算法正确性。
基于哈希表的解决方法
#include <iostream>
#include <vector>
#include <unordered_map>
int find_non_repeating_integer(const std::vector<int>& nums) {
std::unordered_map<int, int> num_count;
// 遍历数组,统计每个数字出现的次数
for (int num : nums) {
num_count[num]++;
}
// 遍历哈希表,找出出现次数为 1 的数字
for (const auto& a : num_count) {
if (a.second == 1) {
return a.first;
}
}
return -1; // 如果没找到,返回 -1
}
int main() {
std::vector<int> nums_one = { 1, 1, 2, 2, 4, 5, 5 };
std::vector<int> nums_two = { 203, 3434, 4545, 3434, 4545 };
std::vector<int> nums_three = { 90, 1, 3, 90, 3 };
std::cout << find_non_repeating_integer(nums_one) << std::endl;
std::cout << find_non_repeating_integer(nums_two) << std::endl;
std::cout << find_non_repeating_integer(nums_three) << std::endl;
return 0;
}
用哈希表去存储数组中的数据,并统计每个数字出现的次数,之后遍历哈希表找出出现次数为1的数字。