题目
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,3,2]
输出: 3
示例 2:
输入: [0,1,0,1,0,1,99]
输出: 99
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-number-ii
解析
对于三个重复的数和一个单独的数,其二进制位的1的个数要么是3的整数倍,要么除以3的余数是1,其结果就是单独的这个数在该位的二进制的值。所以本题可以遍历二进制32位的1的个数,如果该位1的个数是3的整数倍,说明单独的这个数二进制该位是0;如果该位1的个数除以3的余数是1,说明单独的这个数二进制该位是1;
代码
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res=0;
for(int i=0;i<32;i++)//一个数的二进制共有32位,查看每一位的1的个数是否是3的倍数
{
int cnt=0;
for(int j=0;j<nums.size();j++)//计算nums中每一个数在i位1的个数
{
cnt+=(nums[j]>>i)&1;
}
res|=(cnt%3)<<i;
//如果在该位1的个数是3的倍数,则单独的数在该位为0;如果该位1的个数为1,则单独数在该位为1
}
return res;
}
};
备注
1.任何数和0做位或运算,还等于原来的数;
2.任何数和0做异或运算,还等于原来的数;
3.对于一个非空数组,某个元素只出现一次,其他元素出现k次,
3.1如果k为偶数,则使用异或运算;
3.2如果k为奇数,则先统计二进制每一位1的个数,然后取每个数除以k的余数,该余数即为单独元素的二进制值;