LeetCode——面试题17.04 消失的数字

消失的数字

  • 题目
  • 思路
  • 代码
  • 结果
  • 改进思路
  • 改进代码
  • 结果
  • 再改进思路
  • 再改进代码
  • 结果
  • 最终最精简的代码

题目

数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?

思路

先不要考虑在O(n)时间内完成,怎么解决这道题,直观的想法,先排序,再遍历一遍,当 i!= nums[i] 的时候,就break。那么,如果万一刚刚好缺失的是最后一个数呢,即缺失n。

这个也是没问题的,因为如果 i != nums[i] 这个条件没有成立,最后的话,i是等于 n的,这个时候,我们也直接输出即可。

代码

import java.util.Arrays;

class Solution {
    public int missingNumber(int[] nums) {
        //排序
        Arrays.sort(nums);
        int i=0;
        for (;i<nums.length;++i)
            if (i!=nums[i])
                break;
        return  i;
    }
}

结果

LeetCode——面试题17.04 消失的数字_第1张图片

改进思路

既然我们排好序了,再这样一个一个遍历,就很浪费排序这个过程了,可以利用二分法来找出结果。

改进代码

import java.util.Arrays;

class Solution {
    public int missingNumber(int[] nums) {
        //排序
        Arrays.sort(nums);
        int left=0;
        //因为搜索到最后,可能是n缺失,所以,这里需要将right扩大到n
        int right=nums.length-1;
        int middle=0;
        while (left<right)
        {
            middle=left+(right-left)/2;
            if (middle==nums[middle])
                left=middle+1;
            else
                right=middle-1;
        }
        int a=middle-1;
        if (a<0)
            a=0;
        int b=middle+1;
        if (b>nums.length-1)
            b=nums.length-1;
        int i=a;
        for (;i<=b;++i)
        {
            if (nums[i]!=i)
             break;
        }
        return i;
    }
}

结果

LeetCode——面试题17.04 消失的数字_第2张图片
可能是测试的例子不够多,所以,二分搜索好像并没有快多少。

再改进思路

因为我们知道,两个相同的数,进行异或,结果为0,且异或是没有顺序的。因为题目说是从0-n中有一个数字没有,我们先拿那个数,异或一遍0-n,再去异或数组,就能找出那个数。

再改进代码

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

结果

LeetCode——面试题17.04 消失的数字_第3张图片
虽然达到了双百了,但是其实,上面那个代码还可以再精简一下,因为我们观察两个for循环,循环的范围就缺了个 nums.length(),,所以,最终代码还可以这样子修改。

最终最精简的代码

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

你可能感兴趣的:(LeetCode)