剑指 Offer 56 - II. 数组中数字出现的次数 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

来源:力扣(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]  进行统计

30 0 1 1二进制表示
40 1 0 0二进制表示
30 0 1 1二进制表示
30 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;

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值