一.题目描述
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
示例 1:
输入: [0,1,3]
输出: 2
示例 2:
输入: [0,1,2,3,4,5,6,7,9]
输出: 8
限制:
1 <= 数组长度 <= 10000
二.题目解析
public int missingNumber(int[] nums) {
/*for循环遍历,利用0-n-1递增排序数组的特征
时间复杂度O(n)
* */
if(nums == null || nums.length == 0){
return -1;
}
//命中只有一个元素的情况或者检验有多个元素的第一个元素
if(nums[0] != 0){
return 0;
}
//依次与后一个元素相比
for (int i = 0; i <= nums.length - 2; i++) {
if(nums[i+1] != nums[i] + 1){
return nums[i] + 1;
}
}
return nums[nums.length - 1] + 1;
}
2.
public int missingNumber(int[] nums) {
if(nums == null || nums.length == 0){
return 0;
}
int i;
//nums.length == n - 1
for(i = 0;i < nums.length;i++){
if(i != nums[i]){
return i;
}
}
//说明遍历到数组末尾(下标n-2)都没有出现缺失数字,那么缺失的数字是n - 2 + 1
if(i == nums.length){
return nums.length;
}
return 0;
}
3.二分法
public int missingNumber1(int[] nums) {
/*二分法,问题转换成去寻找一个值和下标不相等的元素
每次判断可以过滤掉一半元素
时间复杂度O(logn)
* */
if(nums == null || nums.length == 0){
return -1;
}
int start = 0;
int end = nums.length - 1;
int res = -1;
while (start < end){
int mid = (start + end) /2;
//说明前半部分没有缺失元素
if(start == nums[start] && mid == nums[mid]){
start = mid + 1;
}else{//说明前半部分有缺失元素
end = mid;
}
}
if(start == end &&nums[start] != start){
return start;
}else{
return start + 1;
}
}