1.题目
2.思路
看这个数据范围和题目,一开始直接想到的就是哈希表。时间复杂度O(n)。很快就写出来了。但是在面试过程中面试官可能想考察的是位运算。听说这道题字节面试经常考。(比如限制你不能有额外的空间,保证空间复杂度为O(1)).
位运算应该怎么处理呢?
这道题的特殊性在于其他所有数字都出现3次。位运算无非就是与、或、非、异或。异或在处理出现次数两次的时候非常秒。因为2 xor 2 xor 3 = 3.异或可以消除相同的。这里是三个数,不能用异或消除完。
那么与操作的可能性就很大了。这里采取的是按位与操作,如果是三个数相同的话,那么按位与出来的和%3应该等于0,剩下的数字就是最终要找出的数字。
用一个变量temp记录所有num第i位与操作的和,如果% 3等于0,则说明要找的那个数第i位为0.
如果不为0, 说明要找的那个数第i位为1,所以使用ans += temp << i.
时间复杂度--O(30 * N),空间复杂度O(1)
比哈希表的时间稍微多一点,但是空间复杂度优化O(1)
class Solution {
public int singleNumber(int[] nums) {
int n = nums.length;
int ans = 0 ;
int temp;
for(int i = 30; i >= 0 ; i--){
temp = 0;
for(int num : nums){
temp += (num >> i & 1);
temp %= 3;
}
temp <<= i;
ans += temp;
}
return ans;
}
}
注意:
num 要右移动,获取第i位数字。(num >> i &1)
temp要左移,要乘上2^i;(temp << i)
3.结果