每周一题:0~n-1中缺失的数字(更新JS)
题目:
一个长度为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
代码:
var missingNumber = function(nums) {
let index=0;
for(let i=0;index<nums.length;){
if(nums[i]!==index){
break;
}else{
i++;
index++;
}
}
return index;
};
通过率:


思路:
我选择遍历,此题相当于用循环一个一个做对比,找出数组中不存在的那个数字。
会这么做首先基于题目的性质,这道题数组中只缺失一个数字,而且数组内数字是连续的,所以使用遍历可以求出来,假如缺失的数字有两个甚至更多,代码的执行耗时就会更长,这种情况下就不能再使用暴力解法破解了,应该选择如二分法等能够简化时长的函数方式。
声明变量index,赋值为0,用来做和数组进行对比的数字。
建立for循环,声明局部变量i赋值0,条件为当变量index小于数组长度时该循环生效,否则不执行循环。根据题目要求可知不存在数组内无缺失数字的情况,所以用这个条件可以完成遍历循环。
接着进行if—else条件判断,将i作为数组下标提取数字,和index的数值进行对比,假如不相同,则退出循环返回此时index的数值;如果相同,i和index的数值各加一后继续循环进行判断,一直到找出不相等的数字。
误区:
var missingNumber = function(nums) {
let index=0;//遍历数组,找出不在数组中的那个数字
for(index<nums.length;++index;){
if(nums[index] != index){
break;
}
}
return index;
};
第一次提交时我将循环的条件写错了,导致最后输出的结果和预期结果不一样,数组为[1],输出结果index为1,而预期结果为0。因为我使用的方法不对,将++index放在了循环开始,所以最后输出的结果比预期值大,导致了运行错误。
所以在写循环之前一定要注意条件,这里我将+号提到index之前,导致输出的值不对,而且判断没有写全,这个循环最后也是无法成立的。
代码优化:
这里使用二分法来进行求解。
代码如下:
利用二分查找:
声明三个变量,变量left 指向 0,即数字最开始的元素(注意不一定是数组的最开始元素),right 指向数组的最后一个元素,然后计算中间坐标 mid。
这里有一个前提,根据题意,可以知道mid > nums[mid]这种情况不存在。所以我们在写判断语句时候可以排除这种情况,直接用if-else结构。假如题目要求变更,我们就要重新设置判断条件。
如果mid = nums[mid],说明在[0, mid]范围内不缺失数字,然后将left 更新为 mid + 1;如果mid < nums[mid],说明[mid, right]范围内不缺失数字,将right 更新为 mid - 1,借用这种方法不断地找出中数缩小查找范围。
检查 left 是否小于等于 mid,若成立,返回第 2 步;否则,向下执行。
最后返回 left的数值即可。
通过率如下:

浙公网安备 33010602011771号