[leetCode]Single Number III

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

思路:要求返回只出现过一次的两个数。分两步:
1、将这两个数以某种形式挑出来;
2、将以某种形式挑出来的两个数分开;
结合Single Number 1
我们可以通过对整个数组遍历异或,返回只出现一次的两个数的异或值。第二步就是怎么通过这个异或值分开这两个数。

第二步可以通过标志位来实现,异或后的结果中不为0的位均表示这两个只出现过一次的数在这些位上不相同。因此,我们可以以其中一个1为标志位,实现两个数的拆分。


/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */

int* singleNumber(int* nums, int numsSize, int* returnSize) 
{
    int num = 0;  
    int value = 0;

int firstDiffBit = 1;
int categoryNum;

int *numsOnce;  // malloc memory
if ( !(numsOnce = (int*)malloc(sizeof(int) * 2)) )
{
    printf("malloc Failed!\n");
    return NULL;
}

while(num < numsSize)  // 返回两个只出现过一次的数的异或值
    value ^= nums[num++];

while( !(value & firstDiffBit) )
    firstDiffBit <<= 1;  //!< 两个只出现过一次的数的第一位不相同的位置

for(categoryNum = 0; categoryNum < 2; ++categoryNum)
{
    int categoryVal = 0;

    for(num = 0; num < numsSize; ++num)  //遍历两遍
        categoryVal ^= ( !(firstDiffBit & nums[num]) == categoryNum) ?  nums[num]:0;

    numsOnce[categoryNum] = categoryVal;
}

if (returnSize)
{
    *returnSize = 2;
}
return numsOnce;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值