剑指offer 56- I 数组中数字出现的次数

目录

前言

题目

思路

第一步

第二步

第三步

代码实现


前言

小伙伴们大家好!今天 up 主为大家带来的是程序员必刷题之剑指offer中的一道比较简单,但同时又是很重要的一道题:数组中数字出现的次数。

题目

力扣上题目描述如下所示:

好的,那么如上题所描述的一样,该数组中除了两个数字只出现了一次,其他数全部都出现了两次。那么我们就可以理解题目所说的了。

其次,该题目要求了时间复杂度以及空间复杂度,所以我们必须得在一定的范围内去做。

思路

第一步

我们知道,有一种操作符叫做异或操作符,它的特性是两元素异或时,二进制位相同为0,不同为 1。因为这个数组的特性就是除了两个单独出现的元素之外,其他元素都是成对出现的。如果我们将该数组中所有元素全部异或到一起,那么得到的便是两个单独的元素的异或值。

第二步

因为该异或值最后的结果是两个不同的元素,那么就说明两个不同的数的二进制位一定有一位是不相等的,所以,我们需要找出这个不相等的二进制位的位置 pos 。代码如下所示:

第三步

当我们找到了这个二进制位之后,我们会将该整个数组分为两部分。第一部分是 pos 位置为 0 的数,第二部分是 pos 位置为 1 的数,然后将这两组数分别异或在一起,最后得到的便是两个单独出现的数,将其放入数组中即可。

代码实现

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* singleNumbers(int* nums, int numsSize, int* returnSize){
    int* arr = (int*)malloc(2*sizeof(int)); 
    *returnSize=2;
    int i=0;
    int tmp=0;
    //
    for(i=0;i<numsSize;i++)
    {
        tmp^=nums[i];
    }
    int pos=0;
    while((tmp&1)==0)
    {
         tmp=tmp>>1;
         pos++;
    }
    arr[0]=0;
    arr[1]=0;
    for(i=0;i<numsSize;i++)
    {
        if(((nums[i]>>pos) &1)==1)
           arr[0]^=nums[i];
        else
           arr[1]^=nums[i];  
    }
    return arr;
}

对于上述原码,可能一些小伙伴会有疑问,为什么这里动态内存开辟了两个空间,然后前面会将*returnSize 赋值为 2,明明原先的数组可以存放的下。

其实这里是因为力扣上需要我们这样去做,然后平台才能审核代码。也就是需要一个规范。因为该函数在接收我们的返回值值时,是用 returnSize 接收的,所以这里必须要将 *returnSize 的值赋为 2.用以接收传递的 arr 数组。

好的,那么本为到此就结束啦!如有问题,还请指正呀! 

                                              

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值