136. 只出现一次的数字
算法掌握:
- 位运算(异或 ^)
- 常见的位运算操作:
- 与运算(&):对两个操作数的每个对应比特位执行 AND 运算,只有当两个位都为 1 时,结果位才为 1。
- 或运算(|):对两个操作数的每个对应比特位执行 OR 运算,只要其中一个位为 1,结果位就为 1。
- 异或运算(^):对两个操作数的每个对应比特位执行 XOR 运算,当两个位不同时结果位为 1,否则为 0。
- 取反运算(~):反转操作数的每个位,将 0 变为 1,将 1 变为 0。
- 左移运算(<<):将操作数的比特位向左移动指定的位数,低位补 0。
- 右移运算(>>):将操作数的比特位向右移动指定的位数,高位补符号位(负数补 1,正数补 0)。
解题思路:
如果不考虑 线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间 的情况。 直接开个hash表去重查询没有重复的即可,或者用排序后相邻前后比较即可 本题考查对位运算的异或
首先理解 什么是异或运算 -> 对两个操作数的每个对应比特位(二进制位)执行 XOR 运算,当两个位不同时结果位为 1,否则为 0。
异或运算有以下三个性质。
任何数和 0 做异或运算,结果仍然是原来的数,即 a ⊕ 0 = a
任何数和其自身做异或运算,结果是 0,即 a ⊕ a = 0
异或运算满足交换律和结合律, 即 a ⊕ b ⊕ a = b ⊕ a ⊕ a = b ⊕ (a ⊕ a) = b ⊕ 0 = b
根据 第一个性质和第二个性质 自身相互异或为 0,自身与 0 异或为本身,将所有的值都异或一遍,相同的都为0,剩下一个单独的一定是与 0 异或得本身
java code:
class Solution {
public int singleNumber(int[] nums) {
int n = nums.length;
int res = 0;
for(int i = 0; i < n; i++){
res ^= nums[i];
}
return res;
}
}
c++ code:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res = 0;
for(int num : nums) res ^= num;
return res;
}
};