在一个数组 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来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof
思路:统计出数组中所有的数,第零位合计有多少1,第1位合计有多少1,第31位合计有多少1,用0-31位统计出的1的个数去%3,找出余数为1的那些位,这些位的组合就是出现一次的这个数
eg:对nums = [3,4,3,3] 进行统计
3 0 0 1 1 二进制表示 4 0 1 0 0 二进制表示 3 0 0 1 1 二进制表示 3 0 0 1 1 二进制表示 每一位有1的个数 0 1 3 3 统计后的结果是: 0 1 3 3 ,然后每一位都%3 得到: 0 1 0 0 就是题目要求的数字
思路难点:如何组合余数为1的那些位,假设第j位为1,可以通过1左移j位,然后与0进行按位或的运算。重复该步骤,直到遍历完32位(int是4个字节32个比特位)。
思路图:
代码如下:
int singleNumber(int* nums, int numsSize){
int a[32]={0}; // 保存每一位上1的个数
//进行统计数组中数,二进制每一位上1的个数
for(int i=0;i<numsSize;i++)
{
for(int j=0;j<31;j++)
{
if(nums[i]>>j & 1==1)
a[j]++;
}
}
//将余数为1的每一位组合起来
int x=0;
for(int k=0;k<32;k++)
{
if(a[k]%3!=0)
x=x|(1<<k);
}
return x;
}