剑指 Offer 53 - II. 0~n-1中缺失的数字
首先观察题目给我们的条件,有序递增数组中找元素,比较自然地会往二分上联系。一般的二分,我们找到答案后会直接返回,但这里的二分,我们需要不断缩小空间,直到找到为止。
class Solution {
public int missingNumber(int[] nums) {
int l= 0;
int r= nums.length - 1;
while (start < end) {
int mid = l + (r - l) / 2;
if (nums[mid] == mid) {
//如果nums[mid] == mid也就是说当前元素的
//下标等于他自己,比如数组[0,1,2,3,4,5]每
//个元素的下标都等于他自己,说明[l,mid]
//没有缺少任何数字,那么缺少的肯定是在[mid+1,r]
l = mid + 1;
} else {
//如果当前元素的下标不等于他自己,比如[0,1,2,4]中
//nums[3]==4,说明说明缺少的数字就在这个区间内
r = mid;
}
}
//如果类似于[0,1,2,3]这种start指向了数组的最后一个,我们让他加1
return l == nums[l] ? l + 1 : l;
}
}
二分的时间复杂度为\(O(nlogn)\),空间复杂度为\(O(1)\)。
再分析时间复杂度更低的算法,由于每个数字都只出现了一次,由此考虑位运算,先从0-n之间的所有数异或,再与原数组中的数字异或一次,这样得到的结果即为丢失的数字。
class Solution {
public int missingNumber(int[] nums) {
int ans = 0, n = nums.length;
for(int i = 1; i <= n; i++) {
ans ^= i;
}
for(int num : nums) {
ans ^= num;
}
return ans;
}
}