給定一個整數陣列 nums,其中恰好有兩個元素只出現一次,其餘所有元素均出現兩次。找出這兩個只出現一次的元素。
輸入:nums = [1, 2, 1, 3, 2, 5]
輸出:[3, 5](順序不重要)
O(n)O(1)xor_all = a ^ b(a、b 為兩個唯一數字)。因 a ≠ b,xor_all 至少有一位為 1。xor_all 中最低位的 1(即 diff = xor_all & (-xor_all)),該位上 a、b 必異(一為 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 xor_all = 0;
for (int i = 0; i < numsSize; i++) {
xor_all ^= nums[i];
}
// 找出最低位的 1
int diff = xor_all & (-xor_all);
int *res = (int*)malloc(2 * sizeof(int));
res[0] = res[1] = 0;
for (int i = 0; i < numsSize; i++) {
if (nums[i] & diff) {
res[0] ^= nums[i];
} else {
res[1] ^= nums[i];
}
}
*returnSize = 2;
return res;
}
O(n),兩次遍歷陣列。O(1),僅使用常數額外空間(不含輸出陣列)。利用異或運算的性質(x ^ x = 0、x ^ 0 = x)與位分組技巧,在線性時間、常數空間內解決問題,展現了位運算的強大威力。