LeetCode_18:Missing Number

1、总结
  • 从方法二看出来,LeetCode的算法场景,其实有很多特定的条件,例如:数据从 0 到 n、一定有一个元素缺失;
  • Array.sort() 请注意,数组在原数组上进行排序,不生成副本
  • 异或运算符的原理和运用知识,位运算符
  • 高斯公式:
    在这里插入图片描述
2、问题

Given an array containing n distinct numbers taken from 0, 1, 2, …, n, find the one that is missing from the array.
Example 1:

	Input: [3,0,1]
	Output: 2

Example 2:

	Input: [9,6,4,2,3,5,7,0,1]
	Output: 8

Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?

3、我的解法

方法一:先排序再找缺失元素
(虽然题目要求定存消耗,但我还是想从简单的写起)

	/**
	 * @param {number[]} nums
	 * @return {number}
	 */
	var missingNumber = function(nums) {
	    let sortedNums = nums.sort((a, b) => {
	        return a - b;
	    });
	    console.log('sortedNums', sortedNums);
	    for(let i = 0; i < nums.length; i++) {
	      if(sortedNums[i] != i) {
	          return i;
	      }
	    }
	    return nums.length;
	};		

时间复杂度和空间复杂度都很差,这里有一个陷阱:如果缺失的元素是最后一个元素,则需要帮它补齐。
在这里插入图片描述

方法二:计算总和,用减法得到缺失元素 受方法一中发现的陷阱引导,数组的最大值等于nums.length。已知数组的长度为nums.length,完整的数组长度应该是nums.length+1,数组元素应该是 [0, 1, 2, …, nums.length],则所有元素的总和为: ( 0 + nums.length) * (nums.length+1) / 2

	 /**
	 * @param {number[]} nums
	 * @return {number}
	 */
	var missingNumber = function(nums) {
	    let maxNum = nums.length;
	    let totalAmount = (0 + maxNum) * (maxNum+1) / 2;
	    for(let i = 0; i < maxNum; i++) {
	      totalAmount -= nums[i];
	    }
	    return totalAmount;
	};

这个方法倒是满足了题目固定内存消耗的要求,时间和空间复杂度也快了很多,但是看比例还不是最优解。
在这里插入图片描述

4、其他解法

方法一:排序方法的优化
Array.sort() 方法会变更原来的数组,不产生副本,因此方法一不需要用额外的变量承接排序的结果,去掉这一步,性能会节省一点:

	/**
	 * @param {number[]} nums
	 * @return {number}
	 */
	var missingNumber = function(nums) {
	    nums.sort((a, b) => {
	        return a - b;
	    });
	    // console.log('nums', nums);
	    for(let i = 0; i < nums.length; i++) {
	      if(nums[i] != i) {
	          return i;
	      }
	    }
	    return nums.length;
	};		

在这里插入图片描述
在这里插入图片描述

方法三:位运算 这个解法的原理其实我不是很懂,额外贴出算法原理供学习
在这里插入图片描述

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

在这里插入图片描述
不得不承认位运算的速度是最快的,不过异或运算符的原理和运用知识还比较欠缺

发现solution 的解法跟我的方法二运用同一个原理:高斯公式,还是挺开心的。

方法四:创建完整的元素Map,遍历所有的nums元素,不在map中的则返回结果
方法四:遍历所有的nums.length+1元素,不在nums中的则返回结果

	/**
	 * @param {number[]} nums
	 * @return {number}
	 */
	var missingNumber = function(nums) {
	    for(let j = 0; j < nums.length+1; j++) {
	        if(nums.indexOf(j) < 0) {
	            return j;
	        }
	    }
	};

这个解法是时间复杂度最差的,应该是O(n2),空间复杂度O(1)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值