268. Missing Number
Given an array containing n distinct numbers taken from 0, 1, 2, …, n, find the one that is missing from the array.
Example 1:
Input: [3,0,1]
Output: 2
Example 2:
Input: [9,6,4,2,3,5,7,0,1]
Output: 8
Note:
- Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
方法1: math
思路:
首先知道了数组长度就知道了sum = 0 + … + n,算出总和后就可以开始遍历,把遇到的数字都减去,剩下的就是the missing number。
Complexity
Time complexity: O(n)
Space complexity: O(1)
class Solution {
public:
int missingNumber(vector<int>& nums) {
int n = nums.size(), sum = n * (n + 1) / 2;
for (int a: nums) {
sum -= a;
}
return sum;
}
};
方法2: bit manipulation
思路:
基于两个facts:
- 0 ^ a = a
- a ^ b ^ a = b
我们首先想办法异或累计0…n的所有数字,然后同时与nums[i]里的所有数字也异或一遍。这样出现过的数字都抵消了,剩下的就是the missing number。
易错点
- 初始化result = n,或者最后别忘了累加上去。
Complexity
Time complexity: O(n)
Space complexity: O(1)
class Solution {
public:
int missingNumber(vector<int>& nums) {
int n = nums.size(), result = n;
for (int i = 0; i < n; i++) {
result ^= i;
result ^= nums[i];
}
return result;
}
};
方法3: binary search
思路:
如果数组排好序的话,二分法可以比上面的两种方法更快。我们二分法查找的目标是:第一个nums[i] > i的位置。
Complexity
Time complexity: O(log n)
Space complexity: O(1)
class Solution {
public:
int missingNumber(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
sort(nums.begin(), nums.end());
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > mid) {
right = mid;
}
else {
left = mid + 1;
}
}
if (nums[left] > left) return left;
return nums.size();
}
};