Leetcode No.268 Missing Number(缺失数字)
题目链接:
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 Integer */ 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) { $sum = $n = count($nums); for($i = 0; $i < $n; $i++) { $sum ^= $i ^ $nums[$i]; } return $sum; }
举一反三,我们也可以利用异或的性质来求重复的数字。
最后,由于PHP对数组有很多自带函数,可以用一行代码解决这个问题。
/** * @param Integer[] $nums * @return Integer */ function missingNumber($nums) { return current(array_diff(range(0,count($nums)),$nums)); }
1 Comment
写的很好,点赞