剑指 Offer 56 - II. 数组中唯一只出现一次的数字
在一个数组 nums
中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
示例 1:
输入: nums = [3,4,3,3]
输出: 4
示例 2:
输入: nums = [9,1,7,9,7,9,7]
输出: 1
限制:
1 <= nums.length <= 10000
1 <= nums[i] < 2^31
解题思路
如果一个数字出现三次,那么它的二进制表示的每一位(0
或者1
)也出现三次。如果把所有出现三次的数字的二进制表示的每一位都分别加起来
,那么每一位的和都能被3整除
。
现在有一个数字只出现了一次,其他数字都出现了三次,那么我们用上述思路把数组中所有元素的二进制表示的每一位都分别加起来
,其实也就是统计每一位出现1
的次数总和,那么每一位模3
后就是那个只出现一次的数字的在该位的值(0
或者1
)。
Java代码
class Solution {
public int singleNumber(int[] nums) {
if(nums.length == 1) return nums[0];//题目告知长度大于等于1
int[] bitSum = new int[32];//统计每一位出现次数的总和,其实也就是统计每一位出现1的次数总和
for(int i = 0;i < nums.length;i++){
int bitMask = 1;//注意bitMask是在第二个for之外,即对每个数字,bitMask起始是1
for(int j = 31;j >= 0;j--){
if((nums[i] & bitMask) != 0){//当前位是否是1
bitSum[j]++;
}
bitMask = bitMask << 1;//该看前一位是否是1了
}
}
//得到那个只出现一次的数字
int res = 0;
for(int i = 0;i < 32;i++){
res = res << 1;
res += bitSum[i] % 3;
}
return res;
}
}