每周一题: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之前,导致输出的值不对,而且判断没有写全,这个循环最后也是无法成立的。

 

代码优化:

  这里使用二分法来进行求解。

代码如下:

var missingNumber = function(nums) {
    let left = 0,
        right = nums.length - 1;
    while (left <= right) {
        let mid = Math.floor((left + right) / 2);
        if (mid === nums[mid]) {
            left = mid + 1;
        } else if (mid < nums[mid]) {
            right = mid - 1;
        }
    }

    return left;
};
 
思路:

  利用二分查找:

  声明三个变量,变量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的数值即可。

通过率如下:

posted on 2020-05-08 16:20  沈卢  阅读(394)  评论(0)    收藏  举报

导航