0

Given an array of size n. It contains numbers in the range 1 to n. Each number is present at least once except for 2 numbers. Find the missing numbers. eg. an array of size 5 elements are suppose 3,1,4,4,3

one approach is

static int k;
for(i=1;i<=n;i++)
{
  for(j=0;j<n;j++)
  {
    if(i==a[j])
      break;
   }
    if(j==n)
    {
      k++;
      printf("missing element is", a[j]);
    }

  if(k==2)
    break;}

another solution can be.. for(i=0;i

dreamer
  • 478
  • 1
  • 11
  • 24
  • 2
    @dreamer: Remember to upvote useful answers (once you have the right) and accept the most useful answer (earliest if multiple were most useful). – Seth Robertson May 25 '11 at 18:39
  • Duplicate of http://stackoverflow.com/questions/3492302/easy-interview-question-got-harder-given-numbers-1-100-find-the-missing-number – ccozad May 25 '11 at 18:54
  • 1
    hmmm ... `for (j = 0; j < n; j++) if (j == n) /* never happens */;` – pmg May 25 '11 at 18:58

12 Answers12

4

Let me First explain the concept:

You know that sum of natural numbers 1....n is (n*(n+1))/2.Also you know the sum of square of sum of first n natural numbers 1,2....n is n*(n+1)*(2n+1)/6.Thus you could solve the above problem in O(n) time using above concept.

Also if space complexity is not of much consideration you could use count based approach which requires O(n) time and space complexity.

For more detailed solution visit Find the two repeating elements in a given array

Algorithmist
  • 6,657
  • 7
  • 35
  • 49
  • the two missing numbers here are replaced by some other numbers between i to n..(each number is present atleast once).. so ur logic does not work for this case.. – dreamer May 26 '11 at 11:57
2

I like the "use array elements as indexes" method from Algorithmist's link.

Method 5 (Use array elements as index) Thanks to Manish K. Aasawat for suggesting this method.

traverse the list for i= 1st to n+2 elements
{
check for sign of A[abs(A[i])] ;
if positive then
   make it negative by   A[abs(A[i])]=-A[abs(A[i])];
else  // i.e., A[abs(A[i])] is negative
   this   element (ith element of list) is a repetition
}

The only difference is that here it would be traversing 1 to n. Notice that this is a single-pass solution that uses no extra space (besides storing i)!

Footnote:

Technically it "steals" some extra space -- essentially it is the counter array solution, but instead of allocating its own array of ints, it uses the sign bits of the original array as counters.

trutheality
  • 23,114
  • 6
  • 54
  • 68
1

I haven't checked or run this code, but you should get the idea.

int print_missing(int *arr, size_t length) {
  int *new_arr = calloc(sizeof(int) * length);
  int i;
  for(i = 0; i < length; i++) {
    new_arr[arr[i]] = 1;
  }
  for(i = 0; i < length; i++) {
    if(!new_arr[i]) {
      printf("Number %i is missing\n", i);
    }
  }
  free(new_arr);
  return 0;
}

Runtime should be O(2n). Correct me if I'm wrong.

rhardih
  • 863
  • 1
  • 10
  • 18
  • `new_arr` is one element short. `i` can be equal to `length`. Similarly, the second loop should be `for (i = 1; i <= length; i++)`. – ikegami May 25 '11 at 19:21
  • this is taking a space complexity of o(n)... wat to do if there is a space constraint.. – dreamer May 26 '11 at 11:58
1

Use qsort() to sort the array, then loop over it once to find the missing values. Average O(n*log(n)) time because of the sort, and minimal constant additional storage.

Lee D
  • 116
  • 3
0

We can use the following code to find duplicate and missing values:

    int size = 8;
    int arr[] = {1, 2, 3, 5, 1, 3};
    int result[] = new int[size];

    for(int i =0; i < arr.length; i++)
    {
        if(result[arr[i]-1] == 1)
        {
            System.out.println("repeating: " + (arr[i]));
        }
        result[arr[i]-1]++;
    }

    for(int i =0; i < result.length; i++)
    {
        if(result[i] == 0)
        {
            System.out.println("missing: " + (i+1));
        }
    }
0

This is an interview question: Missing Numbers. condition 1 : The array must not contain any duplicates. The complete solution is :

public class Solution5 {
public static void main(String[] args) {

    int a[] = { 1,8,6,7,10};
    Arrays.sort(a);
List<Integer> list = new ArrayList<>();
int start = a[0];
for (int i = 0; i < a.length; i++) {
    int ch = a[i];   
    if(start == ch) {
        start++;
    }else {
     list.add(start);
     start++;
     //must do this 
     i--;
    }
}//for
System.out.println(list);
}//main

}
Soudipta Dutta
  • 1,353
  • 1
  • 12
  • 7
0

It is unclear why the naive approach (you could use a bitfield or an array) of marking the items you have seen isn't just fine. O(2n) CPU, O(n/8) storage.

Seth Robertson
  • 30,608
  • 7
  • 64
  • 57
  • for(i=0;i – dreamer May 26 '11 at 12:29
  • @dreamer: I'm not sure I buy this answer. Even ignoring that you are changing the source array which might not be good (but apparently is for you). Consider array[3,1,3,3,2] (missing 4,5). Your look will run infinitely since a[i] and a[a[i]-1] have the same (incorrect) value and you never change i. – Seth Robertson May 26 '11 at 13:16
  • when the a[i] and a[a[i]-1] will have the same value then the loop terminates.. while loop checks a[i]!=a[a[i]-1].. pay close attention to it.. – dreamer May 26 '11 at 13:47
  • @robertson.. the value of the source array is not changed.. its just swapped.. even wen we do sorting tht applies.. i dont think tht can be of concern.. – dreamer May 26 '11 at 13:48
0

If you are free to choose the language, then use python's sets.

numbers = [3,1,4,4,3]
print set (range (1 , len (numbers) + 1) ) - set (numbers)

Yields the output

set([2, 5])
Hyperboreus
  • 31,997
  • 9
  • 47
  • 87
0

Here you go. C# solution:

static IEnumerable<int> FindMissingValuesInRange( int[] numbers )
{
  HashSet<int> values = new HashSet<int>( numbers ) ;

  for( int value = 1 ; value <= numbers.Length ; ++value )
  {
    if ( !values.Contains(value) ) yield return value ;
  }
}
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • i am afraid that you didn't saw the tag "C".Could you please elucidate your approach. – Algorithmist May 25 '11 at 19:09
  • @Algorithmist: I did see it (in fact, I put it there). I'm just not going to do somebody's homework for them. Elucidation: The source array is a bag; from that derive the set of values it contains. From the set of integers 1-N inclusive, return those missing from the initial set of values. – Nicholas Carey May 25 '11 at 19:13
0

I see a number of problems with your code. First off, j==n will never happen, and that doesn't give us the missing number. You should also initialize k to 0 before you attempt to increment it. I wrote an algorithm similar to yours, but it works correctly. However, it is not any faster than you expected yours to be:

int k = 0;
int n = 5;
bool found = false;
int a[] = { 3, 1, 4, 4, 3 };

for(int i = 1; i <= n; i++)
{
  for(int j = 0; j < n; j++)
  {
    if(a[j] == i)
    {
        found = true;
        break;
    }
  }
  if(!found)
  {
      printf("missing element is %d\n", i);
      k++;
      if(k==2)
        break;
  }
  else
      found = false;
}

H2H

Nick Rolando
  • 25,879
  • 13
  • 79
  • 119
0

using a support array you can archeive O(n)

int support[n];

// this loop here fills the support array with the
// number of a[i]'s occurences
for(int i = 0; i < n; i++)
    support[a[i]] += 1; 

// now look which are missing (or duplicates, or whatever)
for(int i = 0; i < n; i++)
    if(support[i] == 0) printf("%d is missing", i);
BlackBear
  • 22,411
  • 10
  • 48
  • 86
0

**

 for(i=0; i < n;i++) 
{   

while((a[i]!=i+1)&&(a[i]!=a[a[i]-1])
{

swap(a[i],a[a[i]-1]); 
} 

for(i=0;i< n;i++) 
{ 
if(a[i]!=i+1) 
printf("%d is missing",i+1); } 
this takes o(n) time    and o(1) space

========================================**

dreamer
  • 478
  • 1
  • 11
  • 24