<leetcode>268. Missing Number

来源:互联网 发布:矛盾矩阵 编辑:程序博客网 时间:2024/06/06 02:59

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

For example,
Given nums = [0, 1, 3] return 2.

Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
看了discuss之后,总结了三种解法:
1、最直接的解法就是用不差数的数组元素之和减去给定数组元素的和,得到的结果就是丢失的数(不差数的数组其实就是一个等差数列)
代码实现:

public class Solution {    public int missingNumber(int[] nums) {        int n = nums.length;        int sum = n * (n + 1)/2;        int sum1 = 0;        for (int num : nums){            sum1 += num;        }        return sum - sum1;    }}

注意等差数列的求和公式:Sn=na1+n(n-1)d/2

2、使用位运算,异或的特性就是“相异为一,相同为零”,到十进制表现为a^b^b=a,所以我们将缺数的数组与完整的数组进行异或,最后得到的结果就是丢失的数(只有该数没有相同的数进行匹配)
代码实现:

public class Solution {    public int missingNumber(int[] nums) {        int res = 0;        int i = 0;        for (; i < nums.length; i++){            res ^= i ^ nums[i];        }        return res ^ i;    }}

更简洁的代码写法:可以直接定义res = nums.length;

public class Solution {    public int missingNumber(int[] nums) {        int res = nums.length;//就相当于上面代码块中最后返回值运算的i        for (int i = 0; i < nums.length; i++){            res ^= i ^ nums[i];        }        return res;    }}

3、使用二分查找,当然,如果给定数组没有排好序,则我们还要先排序才能进行二分查找,显然不符合线性时间复杂度的要求,所以,使用二分茶渣的前提是给定数组已经排好序了,此时使用二分查找效率会明显高于上面两种方法。
思路:对于已经排好序的数组,如果数字没有丢失,那么元素的值跟下标应该是相等的,一旦出现了元素值大于下标,则说明丢失的元素在该位置的左边,反之,则在右边。
代码实现:

public class Solution {    public int missingNumber(int[] nums) {        Arrays.sort(nums);        int left = 0;        int right = nums.length;        int mid = 0;        while (left < right){            mid = (left + right) / 2;            if (nums[mid] > mid){               right = mid;             } else {                left = mid + 1;            }        }        return right;    }}
0 0