2

Find the first missing integer in the sequence of integers

[4,5,1,2,6,7] missing is 3

Then when there is repeated integers

[1,2,2,2,5,8,9] still missing 3

When you also have negative

[-2,0, 1,2,] missing -1

[1,2,3,4,5] missing 6 or 0

Can anyone help me find a good algorithm to cover all these cases. I have an algorithm which covers first 2 cases but not sure how to cover all the cases in effective manner.

11
  • 3
    First of all, sort the sequence. Secondly, remove any duplicates. Thirdly, look for any "gap" between values. Lastly, if no gap is found, the "missing" is the next value after the last element in the (sorted) sequence. Commented Mar 8, 2019 at 6:49
  • For the case 1 2 3 4 5 the missing number can also be a 0? Commented Mar 8, 2019 at 6:50
  • 2
    Sort and look for diffs > 1, if you find a difference of 0 it's a duplicate and just continue. Commented Mar 8, 2019 at 6:54
  • 4
    Before you can talk about things that are missing you have to talk about the rules for what you expect to be present. You say in a comment that the sequence 1 2 3 4 5 can be missing 0, then why isn't 0 the first missing integer from the first and second sequence in your question as well? Additionally, in the question you say 6 is the number that is missing. Well, is it 0 or 6? How do you define "first"? Please define the rules for which integers you expect to be present. Commented Mar 8, 2019 at 7:44
  • 1
    The second example is also missing 4, 6, 7. Also, isn't every sequence 'missing' the numbers just off the ends of the sequence? Commented Mar 8, 2019 at 12:05

4 Answers 4

2

What I consider the classic O(n) solution for this problem is to rely on the fact that the array can contain at most N unique numbers, where N is the input's length. Therefore the range for our record is restricted to N.

Since you seem to allow the expected sequence to start anywhere, including negative numbers, we can start by iterating once over the array and recording, L, the lowest number seen. Now use L as an offset so that 0 + L equals the first number we expect to be present.

Initialise an array record of length (N + 1) and set each entry to false. Iterate over the input and for each entry, A[i], if (A[i] - L) is not greater than N, set record[ A[i] - L ] to true. For example:

[-2, 0, 1, 2] ->
N = 4
L = -2

-2 -> -2 - (-2) = 0
   -> record[0] = true

 0 -> 0 - (-2) = 2
   -> record[2] = true

 1 -> 1 - (-2) = 3
   -> record[3] = true

 2 -> 2 - (-2) = 4
   -> record[4] = true

record -> [true, false, true, true, true]

Now iterate over the record. Output the first entry at index i that is set to false as i + L. In our example above, this would be:

record[1] is false

output: 1 + (-2) -> -1
Sign up to request clarification or add additional context in comments.

Comments

2
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main() 
{   
int n;
scanf("%d",&n);
int a[n],i=0;
//Reading elements
for(i=0;i<n;i++){
    scanf("%d",&a[i]);
}
int min=__INT_MAX__,max=0;
//Finding the minimun and maximum from given elements
for(i=0;i<n;i++){
    if(a[i]>max)
    max=a[i];
    if(a[i]<min)
    min=a[i];
}
int len=max-min,diff=0-min,miss;
int b[len];
//Creating a new array and assigning 0
for(i=0;i<len;i++)
    b[i]=0;
//The corresponding index value is incremented based on the given numbers
for(i=0;i<n;i++){
    b[a[i]+diff]++;
}
//Finding the missed value
for(i=0;i<len;i++){
    if(b[i]==0){
        miss=i-diff;
        break;
    }
}
printf("%d",miss);
}

Code Explanation:


1.Find the minimum and maximum in the given numbers.

2.Create an count array of size (maximum-minimum) and iniatizing to 0, which maintains the count of the given numbers.

3.Now by iterating, for each given element increment the corresponding index by 1.

4.Finally iterate through the count array and find the first missing number.

This might help you in solving your problem. Correct me if i'm wrong.

Comments

1

I think, it will be easy to solve sort of problems using data-structure like TreeMap in JAVA, e.g:

treeMap.put(array[i], treeMap.get(array[i]) == null ? 1 : treeMap.get(array[i]) + 1);

So, you are putting key and value to the TreeMap the key represent the digit itself e.g, 1,2,3... and the value represent the occurrence times.

Thus, and by taking advantage of this data-structure (Sort elements for us) you can loop through this data-structure and check which key is missing in the sequence, e.g:

for key in treeMap
   if(key > currentIndex) // this is the missing digit
   if(loop-completed-without-missing-key) // it's not in the array.

Comments

1

Add the numbers to a running array and keep them sorted.

You may also have optional minimum and maximum bounds for the array (to handle your third case, "6 is missing even if not in array"

On examination of a new number: - try inserting it in the sorting array. - already present: discard - below minimum or above maximum: nullify minimum or maximum accordingly - otherwise add in proper position.

To handle an array: sort it, compare first and last elements to expected minimum / maximum. Nullify minimum if greater than first element, nullify maximum if smaller than last element.

There might be a special case if minimum and maximum are both above first or both above last:

 min=5 max=8   array = [ 10, 11, 13 ]

 Here 5, 6, 7, 8 and 12 are missing, but what about 9? Should it be considered missing?

When checking for missing numbers include: - if minimum is not null, all numbers from minimum to first element. - if maximum is not null, all numbers from last element to maximum. - if (last - first) = number of elements, no numbers are missing (total numbers examined minus array size is duplicate count) - otherwise walk the array and report all missing numbers: when checking array[i], if array[i]-array[i-1] != 1 you have a gap.

only "first" missing

You still have to manage the whole array even if you're only interested in one missing number. For if you discarded part of the array, and the missing number arrived, then the new missing number might well have been in the discarded part of the array.

However you might keep trace of what the smallest missing number is, and recalculate with cost of o(log n) only when/if it arrives; then you'd be able to tell which is it in o(1) time. To quickly zero on that missing number, consider that there is a gap between arr[i] and arr[j] iff arr[j]-arr[i] > j-i.

So you can use the bisection method: start with i = first, j = last; if gap(i,j) then c = ceil(i+j)/2. If gap(i, c) then j = c, else i = c, and repeat until j-i = 1. At that point arr[i]+1 is your smallest missing number.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.