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;
}