寻找单身狗在时间复杂度为O(n),空间复杂度为O(1)的解析

  1. 这是进行寻找在一个数组中只出现一个一次的元素的函数.
    int ret=0;
    for(size_t i=0;i<numsSize;i++)
    {
    ret^=nums[i];//^异或标志
    };
  2. 假设有一个二进制序列    (00000010)与(00000001)

    这两二进制序列进行异或,就是相同为0,相异为1;上述异或下来就是00000011。

    第一步,先定义一个变量ret,用这个变量去异或数组中的每个元素,

    然后把数组的每个元素异或到ret上去。
     

    int m=0;
    while(m<32)//找出ret第一位为1的位
    {
       if(ret&(1<m))//1代表的就是00000001   m代表的是向左边移动几次,首先是m=0,移动0次
        break;      //m为1,移动一次现在为00000010;
        else
        ++m; 
    }

    3.在定义一个变量m,用m来代表在计算机里面的32;

    <<这个操作符为左移操作符,举个简单的例子就是

    1<<1(这个是指把1的二进制序列向左边移动一位)

    00000000   00000000  00000000  00000001(1<<1)后

    00000000   00000000  00000000  00000010;直接变成这个了

    上述代码就是判断ret在什么时候第m为1;然后找到这个数;

    if(如果为1 结果为真就直接跳出去)

    int X1,X2=0;
    for(int i=0;i<numSize;++i)
    {
        if(nums[i]&(i<<m)))//判断nums里面为1的一组,不是1的就跳下去为0的一组
            {
                x1^=nums[i];
            }
            {
                X2^=nums[i];
            }
    }

4.现在进行分离操作,前面我们理解了<<位移操作,和异或操作,现在能直接看到

我们先创建两个变量x1,和x2,首先数组numsSize数组进行分组操作,把某一个为1的和某一位为0的现分离出来;

If(nums[i]}&(1<<m));z这个表达式意思就是我们先把第m位位1的(&)先与出来然后再跟x1进行异或操作,x1^=nums[i];结果代表着第m为为1的全部异或在x1上了,因为x1为0,所以相同的数字都被异或掉了,只剩下了一个只出现一次的数字;

else就是第m位为0的数全部异或到了x2上了,又因为x2为0,所以所以相同的数字都被异或掉了,只剩下了一个只出现一次的数字;

最后的结果就是x1,和x2;

int* retArr=(int*)malloc(sizeof(int)*2)
if(retArr==NULL)
    return 0;
retArr[0]=X!;
retArr[1]=X2;
*returnSize=2;

return  retArr;

这个就是c语言比较压抑的地方,我们需要空间时需要去开辟空间不能,直接使用

先在内存里面开辟一个sizeof(int)*2—2个int型的空间

把x1放到retArr[0]里面;代表在内存块为0的地方

把x2放到retArr[1]里面;代表在内存块为1的地方

最后在把retArr返回回去就可以了

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值