• [LintCode] Find the Missing Number


    Given an array contains N numbers of 0 .. N, find which number doesn't exist in the array.

    Example

    Given N = 3 and the array [0, 1, 3], return 2.

    Challenge 

    Do it in-place with O(1) extra memory and O(n) time.

    Solution 1. O(n*logn) runtime using sorting 

    Sort the input array;

    Then iterate through the array and find i that nums[i] != i;

    If found one, return it; If not, return nums.length.

     1 public class Solution {
     2     public int findMissing(int[] nums) {
     3         if(nums == null || nums.length == 0){
     4             return -1;
     5         }
     6         Arrays.sort(nums);
     7         int i = 0;
     8         for(; i < nums.length; i++){
     9             if(nums[i] != i){
    10                 return i;
    11             }
    12         }
    13         return i;
    14     }
    15 }

    Solution 2. O(n) runtime, O(1) space, by swapping elements to make nums[i] = i.

    In solution 1,  the key idea is to change the input array into an ascending order then find the index that nums[index] != index.

    The bottleneck here is the O(n*logn) sorting.  We can leverage the same idea from First Missing Positive and achieve 

    the re-ordering in O(n) runtime by only swapping elements.

    Algorithm: provide the input array the property of nums[i] = i by swapping elements in O(n) time.

    Since there is one number missing from 0 to N, a linear scan of the changed array finds the index i that nums[i] != i, this 

    index is the missing number.

    Each while loop moves the current number nums[i] to its right location that satisfies nums[i] = i. The only exception is that 

    if the array has the number N. Because the largest index of nums is N - 1, nums[N] causes array index out of bound error.

    So if nums[i] == N, we skip swapping it. 

     1 public class Solution{
     2     public int findMissing(int[] nums){
     3         if(nums == null || nums.length == 0){
     4             return - 1;
     5         }
     6         for(int i = 0; i < nums.length; i++){
     7             while(nums[i] != i && nums[i] < nums.length){
     8                 int temp = nums[nums[i]];
     9                 nums[nums[i]] = nums[i];
    10                 nums[i] = temp;
    11             } 
    12         }
    13         int missing = 0;
    14         for(; missing < nums.length; missing++){
    15             if(nums[missing] != missing){
    16                 break;    
    17             }    
    18         }
    19         return missing;
    20     }
    21 }

    Solution 3. O(n) runtime, O(1) space, find summation difference 

    This solution is not good as solution 2 or 4 because the sum here can be very big and causes overflow. 

    The following code uses type long to address this issue. But in the extreme cases even long type may

    overflow.

     1 public class Solution {
     2     public int findMissing(int[] nums) {
     3         if(nums == null || nums.length == 0){
     4             return -1;
     5         }
     6         long sum1 = 0, sum2 = 0;
     7         for(int i = 0; i <= nums.length; i++){
     8             sum1 += i;
     9         }
    10         for(int i = 0; i < nums.length; i++){
    11             sum2 += nums[i];
    12         }
    13         return (int)(sum1 - sum2);
    14     }
    15 }

    Solution 4. O(n) time, O(1) space, Bitwise operation 

    Algorithm:

    1. xor all the array elements, let the result be x1;

    2. xor all numbers from 0 to n, let the result be x2;

    3. x1 ^ x2 gives the missing number.

    Proof of correctness:

    Say we are give A0, A1, A2, A4;  A3 is missing.

    X1 = A0 ^ A1 ^ A2 ^ A4;

    X2 = A0 ^ A1 ^ A2 ^ A3 ^ A4;

    X1 ^ X2 = (A0 ^ A1 ^ A2 ^ A4) ^ (A0 ^ A1 ^ A2 ^ A3 ^ A4)

             =  (A0 ^ A0) ^ (A1 ^ A1) ^ (A2 ^ A2) ^ A3 ^ (A4 ^ A4)

                  = 0 ^ 0 ^ 0 ^ A3 ^ 0

        = A3

     1 public class Solution {
     2     public int findMissing(int[] nums) {
     3         if(nums == null || nums.length == 0){
     4             return -1;
     5         }
     6         int xor1 = 0, xor2 = nums[0];
     7         for(int i = 1; i <= nums.length; i++){
     8             xor1 ^= i;
     9         }
    10         for(int i = 1; i < nums.length; i++){
    11             xor2 ^= nums[i];
    12         }
    13         return xor1 ^ xor2;
    14     }
    15 }

    Related Problems

    Find the Duplicate Number 

    Find the Missing Number II

    Find Missing Positive

  • 相关阅读:
    使用变焦摄影镜头的10条经验
    Savage 2:灵魂拷问者Linux即时战略游戏
    在FlashCom中检测摄像头和麦克风的方法
    Asp.net 在线转Flv
    linux的启动加密
    一个命令轻轻松松重新初始化Ubuntu软件包
    Firefox扩展开发学习杂记
    使用 XUL 实现浏览器扩展,第 1 部分: 使用用户界面特性创建一个 Firefox 浏览
    ffmpeg参数解释中文详细
    用mencoder解决ffmpeg转换wmv/asf to flv花屏的问题,并支持rm/rmvb
  • 原文地址:https://www.cnblogs.com/lz87/p/7204849.html
Copyright © 2020-2023  润新知