21.%d\n Bitwise XOR(依位元的互斥或)

春麗 S.T.E.M.
3 min readSep 9, 2021

--

題目給予的條件

Input:[2,2,1]
Output: 1
----------
Input:[4,1,2,1,2]
Output: 4
int singleNumber(int* nums, int numSize) {}

如果輸入的陣列是[2,2,1],答案是1;如果輸入的陣列是[4,1,2,1,2],答案是4,題目說的是要排除重複的陣列元素,沒有重複的那個就是答案

一般法:

for(int i = 0;i < numSize;i++) {
printf("%d\n", nums[i]);
int count = 0;
for(int j = 0;j < numSize;j++) {
if(nums[j] == nums[i]) {
count++;
}
if (count == 1) {
return nums[i];
}
}
return -1;
}

簡單解釋程式碼,先確定迴圈是跑出陣列所有的元素,所以範圍是0..<numSize,宣告一個count,去比對看看兩個相同陣列的元素,如果元素重複,count就加1,然而陣列的元素本來就有重複,所以陣列裡的每個元素去比對陣列裡的所有元素,如果只加1,代表這個元素並沒有和其他元素重複,最後回傳的即是該元素。

如[4,1,2,1,2]中的第一個元素 4,去比對[4,1,2,1,2],此時count只加1,所以回傳該元素即為答案。

最後補上return -1則是因為,如果沒有滿足上述條件,程式會繼續往下跑,但沒有回傳值是未定義行為,所以補上return -1,不過題目給予的陣列其實都是有答案的,也就是並不會跑到這一行,只是為了邏輯的完善而必須補上。

bitwise XOR:

int n = nums[0];
for (int i = 1; i < numSize; i++) {
n ^= nums[i];
}
return n;

互斥或的意思是1與0互斥,11、00不互斥;而bitwise的XOR即是說兩個一般(十進位)數字,以二進位表示後,如以1個byte表示的1與2

00000001 => 1
00000001 => 1
--------
00000000 => 0 XOR
00000001 => 1
00000010 => 2
--------
00000011 => 3 XOR
00000010 => 2
00000001 => 1
--------
00000011 => 3 XOR
00000000 => 0
00000010 => 2
--------
00000010 => 2 XOR

以上是bitwise互斥或的各種情形,可以得到的結論是

  1. a ^ 0 => a
  2. a ^ b => b ^ a(交換律)
  3. a ^ a => 0

這可說是我們利用陣列的第一個元素去trim,陣列的其他所有元素,重複的元素以互斥或去做會等於 0,所以最後會留下不重複的那個數字。

例如 2去對[2,1]做互斥或,2對2做是0,0跟1做是1,最後留下1。

又例如 4去對[1,2,1,2]做互斥或,在運算上,我們可以藉由交換律去看結果,等同於1對[1,2,2,4]做互斥或,所以0=>2=>0=>4,最後留下4,即是我們要的答案。

--

--

春麗 S.T.E.M.
春麗 S.T.E.M.

Written by 春麗 S.T.E.M.

Do not go gentle into that good night, Old age should burn and rave at close of day; Rage, rage, against the dying of the light.

No responses yet