題目
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].
Note:
- The order of the result is not important. So in the above example, [5, 3] is also correct.
- Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
方法
這題是建立在136. Single Number基礎上的
假設nums中2個不同的數為a和b,通過計算nums的異或運算就能求出a和b的異或值,定為c。那么c的二進制表示中,從右開始數的第一個1即為a和b的二進制形式在該位上肯定是不同的值。
假如a = 0101, b = 0011, 那么a^b=0110, 那么a和b是在從右往左數的第二位值不同。設置bit=010,將nums里的每個數&bit, 便可將nums分成2組了,每組的異或值就是a或者b了。
c代碼
#include <assert.h>
#include <stdlib.h>
/**
* 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 i = 0;
int result = 0;
for(i = 0; i < numsSize; i++) {
result ^= nums[i];
}
// int bit = result & (~(result-1));
int bit = 1;
while((result & 1) == 0) {
bit <<= 1;
result >>= 1;
}
int result1 = 0;
int result2 = 0;
for(i = 0; i < numsSize; i++) {
if((nums[i] & bit) == 0)
result1 ^= nums[i];
else
result2 ^= nums[i];
}
int* singleNums = (int *)malloc(sizeof(int)*2);
singleNums[0] = result1;
singleNums[1] = result2;
*returnSize = 2;
return singleNums;
}
int main() {
int returnSize = 0;
int nums[6] = {1,1,2,2,3,5};
int* singleNums = singleNumber(nums, 6, &returnSize);
assert(returnSize == 2);
assert(singleNums[0] == 5);
assert(singleNums[1] == 3);
return 0;
}