剑指offer 56——数组中数字出现的次数(C语言)

数组中数字出现的次数

题目描述

在这里插入图片描述
在这里插入图片描述

题目分析

在这里插入图片描述

其实我们就可以看出来,xorRet 二进制序列中的1的位置对应两个出现一次的数字的二进制序列的位置有着规律
————>xorRet 为1的位置,出现一次的数字x1,x2的位置必然一个是0一个是1。那么问题的解决方法就有了
1、把数组中所有数异或为xorRet
2、取xorRet中的1的位置。
3、根据这个位置对数组中所有元素进行分组,那两个只出现一次的不同数字必然被分到了不同的组中,其他
相同的数字也被分到了一组中。
4、对两组中的数字进行异或。每组最后的异或结果就是x1和x2。

题目实现

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
//思路:把数组中的元素依次全部异或,相同数字必然异或成了0,而且异或也满足结合律,不同的数字异或的结果是非0数字
//     则最后异或的结果就是数组中两个不同数字的异或的结果
int* singleNumbers(int* nums, int numsSize, int* returnSize){
    //1、依次异或
     int xorRet = 0;
     for(int i = 0;i < numsSize;++i)
     {
         xorRet ^= nums[i];
     }
     //2、选出1位置
    int m = 0;
    while(m < 32)
    {
        if(xorRet & (1<<m))
        {
            break;
        } 
        else
        {
           ++m;
        }
          
    }

    //3、分组把x1 x2 分离
    int x1 = 0;
    int x2 = 0;
    for(int i = 0;i < numsSize; i++)
    {
        if(nums[i] & (1<<m)) //和上面如法炮制
        {
            x1 ^= nums[i];
        }
        else
        {
            x2 ^= nums[i];
        }
    }

    int* retArr = (int*)malloc(sizeof(int)*2);
    retArr[0] = x1;
    retArr[1] = x2;
    *returnSize = 2;
    return retArr;
}

到这里就完美解决了!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值