题意
在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
示例 1:
输入:nums = [3,4,3,3]
输出:4
限制:
1 <= nums.length <= 10000
1 <= nums[i] < 2^31
问题分析
采用异或无法解决问题,因为3个相同的数字的异或结果还是该数字,但是还是可以沿用位运算的思路。
如果一个数字出现三次,那么它的二进制表示的每一位(0或者1)也出现三次。如果把所有出现三次的数字的二进制表示的每一位都分别加起来,那么每一位的和都能被3整除。
我们把数组中所有数字的二进制表示的每一位都加起来。如果某一位的和能被3整除,那么那个只出现一次的数字二进制表示中对应的那一位是0,否则就是1。
//C++
class Solution {
public:
int singleNumber(vector<int>& nums) {
int bitSum[32];
fill(bitSum,bitSum+32,0);
for(int i = 0; i < nums.size(); i++){
unsigned bitMask = 1;
for(int j = 31; j >= 0; j--){
int bit = bitMask & nums[i];
if(bit != 0)
bitSum[j] += 1;
bitMask = bitMask << 1;
}
}
unsigned int res = 0;
for(int i = 0; i < 32; ++i){
res = res << 1;
res += bitSum[i] % 3;
}
return res;
}
};
class Solution {
public int singleNumber(int[] nums) {
int[] counts = new int[32];
for(int num : nums) {
for(int j = 0; j < 32; j++) {
counts[j] += num & 1;
num >>>= 1;
}
}
int res = 0, m = 3;
for(int i = 0; i < 32; i++) {
res <<= 1;
res |= counts[31 - i] % m;
}
return res;
}
}