[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

转载于:https://www.cnblogs.com/lz87/p/7204849.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值