2020-10-23 0~n-1中缺失的数字

题目描述

一个长度为 n-1 的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围 0 ~ n-1 之内。在范围 0 ~ n-1 内的 n 个数字中有且只有一个数字不在该数组中,请找出这个数字

题目描述

  • 数字唯一
  • 缺失其中一个

参数说明

/**
 * @param {number[]} nums
 * @return {number}
 */

题解及实现

1. 二分查找

用两指针,i 指针指向最后一位,j 指针指向第一位,考虑到只有一个数字缺失,例如[1,2,3,4],取中点 i+j/2 = 1.5 无论取 1,还是 2,与对应位数字相比都是小的,这说明小数缺失,大数左移,所以将搜索范围缩小至[j,mid-1],此例子中 j==i==0,最后比较此位,若 i>nums[i],说明大数缺失,反之小数缺失

var missingNumber = function (nums) {
  let i = nums.length - 1;
  let j = 0;
  let mid;
  while (j <= i) {
    mid = Number.parseInt((i + j) / 2);
    mid === nums[mid] ? (j = mid + 1) : (i = mid - 1);
  }
  return j; //最后j指向的索引就是结果
};

时间复杂度:O(log(n))

  • 资源使用情况
    • 执行用时:84 ms, 在所有 JavaScript 提交中击败了 81.44%的用户
    • 内存消耗:40.1 MB, 在所有 JavaScript 提交中击败了 6.47%的用户

2. 遍历总和作减法

考虑到数字唯一且只缺失一个,可以将数组中的整数进行累加再被本来应该的总数减

var missingNumber = function (nums) {
  return (
    (nums.length * (nums.length + 1)) / 2 - nums.reduce((a, b) => a + b, 0)
  );
};

时间复杂度:O(n)

  • 资源使用情况
    • 执行用时:76 ms, 在所有 JavaScript 提交中击败了 95.33%的用户
    • 内存消耗:39.7 MB, 在所有 JavaScript 提交中击败了 13.25%的用户
      问题:太慢了

同思路黑科技版

var missingNumber = function (nums) {
  return (nums.length * (nums.length + 1)) / 2 - eval(nums.join("+"));
};
  • 资源使用情况
    • 执行用时:112 ms, 在所有 JavaScript 提交中击败了 8.04%的用户
    • 内存消耗:41 MB, 在所有 JavaScript 提交中击败了 5.03%的用户
      问题:黑科技是用来炫技的,不是拿来用的

3. 数学思维之异或

众所周知,相同的数异或为 0,如果将数组补全为 n 为,比如[0,1,2,3,4],那么其和相应索引之间异或再相加为 0,现缺失了一个数,但我们把索引补全,比如上述缺失 1,但索引补全为 0,1,2,3,4 他们和数组元素进行异或的和就是 1

var missingNumber = function (nums) {
  let i = 0;
  let result = 0;
  for (; i < nums.length; i++) result ^= i ^ nums[i];
  return result ^ nums.length;
};

时间复杂度:O(n)

  • 资源使用情况
    • 执行用时:80 ms, 在所有 JavaScript 提交中击败了 90.78%的用户
    • 内存消耗:39.9 MB, 在所有 JavaScript 提交中击败了 10.86%的用户
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容