268. Missing Number

来源:互联网 发布:手机号码信息查询软件 编辑:程序博客网 时间:2024/06/05 15:11
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?

今天再认真看这道题才发现之前的解法是错误的

    public int missingNumber(int[] nums) {        Arrays.sort(nums);        int i = 0;        while(i<nums.length){            if(nums[i] != i) return i;            i++;        }        return i;    }

排序的时间复杂度是O(nlgn),而且Arrays.sort的空间复杂度也不是O(1)

修改为如下代码,时间复杂度O(n) (每个数字都会被最多操作一次,即放置到正确的位置上)

    public int missingNumber(int[] nums) {        for (int i=0; i<nums.length; i++) {            while (nums[i] != i && nums[i] != nums.length) {                swap(nums, i, nums[i]);            }        }        for (int i=0; i<nums.length; i++) {            if (nums[i] != i) {                return i;            }        }        return nums.length;    }        private void swap(int[] nums, int i, int j) {        int tmp = nums[i];        nums[i] = nums[j];        nums[j] = tmp;    }


看了discuss,还有几种解法

一是二分查找,但是这需要保证输入是有序的

二是先算sum=n(n+1)/2,然后逐个做差,剩下的就是missing num,但是如果数组的数字比较大,求和会overflow

最后一种是位运算,比较好,如下

The basic idea is to use XOR operation. We all know that a^b^b =a, which means two xor operations with the same number will eliminate the number and reveal the original number.
In this solution, I apply XOR operation to both the index and value of the array. In a complete array with no missing numbers, the index and value should be perfectly corresponding( nums[index] = index), so in a missing array, what left finally is the missing number. 

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