力扣链接:力扣136.只出现一次的数字
给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
示例 1 :
输入:nums = [2,2,1]
输出:1
获取所有元素的哈希表,然后判断出现次数为1的那个即可。
class Solution {
public:
int singleNumber(vector<int>& nums) {
unordered_map<int, int> countMap;
for (auto num : nums) {
++countMap[num];
}
int target = 0;
for(auto& entry : countMap) {
if (entry.second == 1) {
target = entry.first;
break;
}
}
return target;
}
};
异或运算的两条性质:
a ^ a = 0
;a ^ 0 = a
。因此,将0与nums中所有元素进行异或运算,最后得到的结果便是只出现一次的数字。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int result = 0;
for (auto num : nums) result ^= num;
return result;
}
};
&
。任何数和0做与运算,结果都是0,即 x & 0 = 0。例如,5(101) & 0 = 0。
任何数和其自身做与运算,结果是自身,即 x & x = x。例如,5(101) & 5(101) = 5(101)。
|
。任何数和0做或运算,结果是自身,即 x | 0 = x。例如,5(101) | 0 = 5(101)。
任何数和其自身做或运算,结果是自身,即 x | x = x。例如,5(101) | 5(101) = 5(101)。
^
。任何数和0做异或运算,结果是自身,即 x ^ 0 = x。例如,5(101) ^ 0 = 5(101)。
任何数和其自身做异或运算,结果是0,即 x ^ x = 0。例如,5(101) ^ 5(101) = 0。
异或运算满足交换律和结合律,即 a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c。例如,5(101) ^ 3(011) ^ 4(100) = 5 ^ (3 ^ 4) = (5 ^ 3) ^ 4。
~
。非运算会反转操作数的所有位。例如,~5(101) = 2(010)。
<<
。左移n位等于乘以2的n次方,即 x << n = x * 2^n。例如,5(101) << 2 = 20(10100)。
左移运算不改变操作数的符号位。
>>
。右移n位等于除以2的n次方,即 x >> n = x / 2^n。例如,20(10100) >> 2 = 5(101)。
逻辑右移运算会用0填充移位后产生的空位。
>>>
。算术右移运算会用符号位填充移位后产生的空位,因此它可以保持负数的符号。例如,对于负数-5(1011) >>> 2 = -2(1110)。