Question
Given an array containing n distinct numbers taken from 0, 1, 2, …, n, find the one that is missing from the array.
For example:
Given nums = [0, 1, 3] return 2.
Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
Idea
给定一个含有n个不重复数字的数组,n个数字来自0, 1, 2, …, n, 找出其中丢失的数字。(这里并没有说明是按序排列的数组)
Xor异或
:由于b^b=0(这里是进行位异或),所以a^b^b=a^0=a.- 这里取a=0,依次与‘i’,‘nums[i]’进行异或运算.
- 如:a = a^0^0^1^1…^k^…n^n = a^k = 0^k = k.
Sum求和
:由于题目告诉只缺少一个数字,故用0~n的和减去数组的和得到的即为要求的数字.- 0~n的和:n(n+1)/2.
BinarySearch
:将数组进行排序后,可以利用二分查找的方法来找到缺少的数字,不过对算法进行略微的改动.
Code
Xor异或—Java
public class Solution {
public int missingNumber(int[] nums) {
int a = 0, i = 0;
for (i=0; i<nums.length;i++){
a = a^i^nums[i];
}
return a^i;
}
}
* 算法中i从0~n-1(因为数组的大小为n),所以在循环结束后,i<=nums[i];
* 如果缺少的数字k<n,则最后a^i以消去最后的nums[n-1];
* 如果缺少的数字k=n,则最后a^i=i,刚好为缺少的数字n;
* 所以最后返回的值为a^i,这里注意i要设置为for循环外的变量。
* 时间复杂度低,Runtime:1ms.
Sum求和—Java
public class Solution {
public int missingNumber(int[] nums) {
int n = nums.length;
int sum = (n+0)*(n+1)/2;
for (int i=0; i<n; i++){
sum -= nums[i];
}
return sum;
}
}
- 算法的时间复杂度为O(n),空间复杂度为O(1)
- Runtime:1ms.
BinarySearch—Java
public class Solution {
public int missingNumber(int[] nums) {
Arrays.sort(nums);
int low = 0;
int high = nums.length;
while (low < high){
int mid = (low+high)/2;
if (nums[mid] > mid) high = mid;
else low = mid+1;
}
return low;
}
}
- 算法这里有部分的变动,需要注意:
high = nums.length
,而不是nums.length-1
,这里相当于high = n,因为搜索范围为0~n;- 循环条件为
low<high
,而不是low<=high
;
- 算法的时间复杂度较前两个要高