Leetcode No.268 Missing Number(缺失數字)
給定一個包含0, 1, 2, ..., n
中 n
個數的序列,找出 0 .. n
中沒有出現在序列中的那個數。
示例 1:
輸入: [3,0,1] 輸出: 2
示例 2:
輸入: [9,6,4,2,3,5,7,0,1] 輸出: 8
說明:
你的演算法應具有線性時間複雜度。你能否僅使用額外常數空間來實現?
分析: 由題可知,0,1,2……n為公差為1的等差數列,求缺失的那個數,只需要用完整序列的和減去當前給定序列的和即可。
等差數列公式:(首項+末項)×項數÷2
/** * @param Integer[] $nums * @return Intege r*/ function missingNumber($nums) { $length = count($nums); $sum = (1+$length)*($length/2); foreach($nums as $num) $sum -= $num; return $sum; }
這種解法很自然並且時間和空間效能也良好。下面提供一種更為巧妙的解法。
另解: 由於異或運算的特性1^1=0,我們可以利用這個特性來消除完整序列和給定序列中相同的值,那麼剩下的就是缺失的那個數。
異或基礎運算如下:
輸入 |
運算子 |
輸入 |
結果 |
1 |
⊕ |
0 |
1 |
1 |
⊕ |
1 |
0 |
0 |
⊕ |
0 |
0 |
0 |
⊕ |
1 |
1 |
異或運算的法則:
1. a ^ a = 0
2. a ^ b = b ^ a
3. a ^b ^ c = a ^ (b ^ c) = (a ^ b) ^ c;
4. d = a ^ b ^ c 可以推出 a = d ^ b ^ c.
5. a ^ b ^ a = b.
運用性質1、2、3我們可以快速求出缺失的數字,程式碼如下:
/** * @param Integer[] $nums * @return Integer */ function missingNumber($nums) { $num = count($nums); $sum = $num; for($i=0;$i<$num;$i++) { $sum ^= $nums[$i]; $sum ^= $i; } return $sum; }
舉一反三,我們也可以利用異或的性質來求重複的數字。