0

How can we find a repeated number in array in O(n) time and O(1) complexity? eg array 2,1,4,3,3,10 output is 3

EDIT: I tried in following way. i found that if no is oddly repeated then we can achieve the result by doing xor . so i thought to make the element which is odd no repeating to even no and every evenly repeating no to odd.but for that i need to find out unique element array from input array in O(n) but couldn't find the way.

Suri
  • 3,287
  • 9
  • 45
  • 75

8 Answers8

3

Without knowing more about the possible values in the array you can't.

With O(1) space requirement the fastest way is to sort the array so it's going to be at least O(n*log(n)).

Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
3

Assuming that there is an upped bound for the values of the numbers in the array (which is the case with all built-in integer types in all programming languages I 've ever used -- for example, let's say they are 32-bit integers) there is a solution that uses constant space:

  1. Create an array of N elements, where N is the upper bound for the integer values in the input array and initialize all elements to 0 or false or some equivalent. I 'll call this the lookup array.
  2. Loop over the input array, and use each number to index into the lookup array. If the value you find is 1 or true (etc), the current number in the input array is a duplicate.
  3. Otherwise, set the corresponding value in the lookup array to 1 or true to remember that we have seen this particular input number.

Technically, this is O(n) time and O(1) space, and it does not destroy the input array. Practically, you would need things to be going your way to have such a program actually run (e.g. it's out of the question if talking about 64-bit integers in the input).

Jon
  • 428,835
  • 81
  • 738
  • 806
  • yes, I thought of that solution also but complexity is O(K*n) where k is no of bits.if k>logn then O(nlogn) will be efficient solution. – Suri Sep 10 '11 at 10:23
  • @Suri: I lost you there. Where does `n` come into the memory requirement complexity? – Jon Sep 10 '11 at 10:25
  • a lot of dynamic languages have no limit on integer size. – Karoly Horvath Sep 10 '11 at 10:26
  • well, you know JS, Ruby and Python. Some JS engines don't have integer types at all, just a double (it's limited but 64bit for this solution is out of the question). Ruby and Python both have unlimited size integers and the they automatically switch to these types so there's no overflow. – Karoly Horvath Sep 10 '11 at 10:34
  • @yi_H: We could split some technical hairs there (i.e. many dynamic languages don't even have *arrays* per se), but in principle I 'll accept this. Certainly this approach has lots of practical limitations. – Jon Sep 10 '11 at 10:39
  • 3
    How is this solution O(1) in space? If we have 0,1,2,3... 2^32-1,2^32-1 as input, it would require you to have an array of size 2^32 bits, size equivalent to = 2^27 integers. It is certainly not O(1). – Nitin Garg Sep 10 '11 at 11:04
  • 1
    @NitinGarg: You have the definition of O(1) wrong. This solution would require an array of size `2^32` *no matter what the input*, hence it's O(1). – Jon Sep 10 '11 at 11:08
  • @Nitin - because it uses a constant amount of space, unrelated to n. Constant terms are reduced to 1. Same goes for time complexity. If I had an algorithm that could solve this problem by iterating over the n elements exactly 5 times, the complexity would not be O(5n), it would be O(n) because the constant factor is dropped (i.e. reduced to 1). As he stated though, it's only technically O(1) because in practical application (say only one number is duplicated), the range of integers has some association with n. – hatchet - done with SOverflow Sep 10 '11 at 11:16
  • 7
    @Jon - by the same technicality you could iterate over the array 2^32 times, where each iteration looks for duplicates of a single number (using only boolean to store whether I've found one, and if I find another then I have a duplicate). Technically, it's O(n), and certainly O(1) space. – hatchet - done with SOverflow Sep 10 '11 at 11:28
  • @hatchet: True. Classic time-space tradeoff... =) – Jon Sep 10 '11 at 11:29
  • @Jon -Now i understand how it is 'technically' O(1).But It means that integer/float/double/long sorting can be done in O(n) as well. – Nitin Garg Sep 10 '11 at 11:31
  • @hatchet -certainly a simpler solution :) – Nitin Garg Sep 10 '11 at 11:33
  • @Nitin Garg: There is no sorting algorithm with O(n) average performance. Some algorithms do have O(n) best-case performance though (e.g. if you give them input that is already sorted). – Jon Sep 10 '11 at 11:37
  • 2
    @Jon - For integer sorting, i can create an array X with 2^32 elements, all initialized to 0. Now i iterate through the original sequence of integers (a1,a2... ai... an) and increment X[ai] by 1 at every step. At the end i just need one loop over X, taking n + 2^32 (constant amount of time) to get the sorted sequence. – Nitin Garg Sep 10 '11 at 11:43
  • @NitinGarg: That's counting occurences, not sorting. Unless I didn't get it correctly? – Jon Sep 10 '11 at 11:52
  • @Jon: Yes, it is a valid sorting algorithm, called [counting sort](http://en.wikipedia.org/wiki/Counting_sort), which is O(n) time if you view k as constant. The property that 'it can't be done faster than O(n*log(n))' applies only to *comparison-based* sorting. – Erik P. Sep 10 '11 at 14:01
  • @Jon,time complexity = O(K*n) in bit sorting k= no of bits suppose eg 1,2,1,2^31 are the element.then by other algo time complexity = O(nlogn)= 2*log4=4 but in case of O(n*k)= 32*4 = 128 hence O(nlogn) complexity is better. bit sorting used when range is less and elements are huge.But as per terminology we can say O(n).But O(n) – Suri Sep 10 '11 at 15:15
  • Suppose N = upper bound n = total no of element. if n< – Suri Sep 10 '11 at 15:30
  • @Jon - It's straightforward to obtain a sorted sequence once you have counted occurrences. – Nitin Garg Sep 13 '11 at 12:58
  • @Suri - i am looking forward to answer to your question. – Nitin Garg Sep 13 '11 at 12:59
  • This is undoubtedly a o(2^32) space ... Using a hashmap at least would take space to o(n). But both solutions won't fulfill the requirements of o(1) space. – Mohamed Taher Alrefaie Mar 07 '15 at 20:18
  • @M-T-A: In Big-Oh notation constant factors can be cast off freely. O(1) and O(2^100) are the same thing. – Jon Mar 07 '15 at 20:44
  • @Jon Allocating 17.7GB of RAM is NOT O(1) ;) – Mohamed Taher Alrefaie Mar 07 '15 at 22:15
  • @M-T-A: It is O(1) if you can tell that you are never going to need more than that just from reading the description of the task. I don't know why we are discussing this, the definition of Big-Oh is not a subjective matter. – Jon Mar 07 '15 at 22:41
1

Use Bit manipulation ... traverse the list in one loop.

  1. Check if the mask is 1 by shifting the value from i.
  2. If so print out repeated value i.
  3. If the value is unset, set it.

*If you only want to show one repeated values once, add another integer show and set its bits as well like in the example below.

**This is in java, I'm not sure we will reach it, but you might want to also add a check using Integer.MAX_VALUE.

    public static void repeated( int[] vals ) {
        int mask = 0;
        int show = 0;
        for( int i : vals ) {
            // get bit in mask
            if( (( mask >> i ) & 1) == 1 &&
                (( show >> i ) & 1) == 0 )
            {
                System.out.println( "\n\tfound: " + i );
                show = show | (1 << i);
            }

            // set mask if not found
            else
            {
                mask = mask | (1 << i);
                System.out.println( "new: " + i );
            }

            System.out.println( "mask: " + mask );
        }
    }
Chris Sullivan
  • 576
  • 5
  • 10
  • Don't forget this logic will work only when you have values of one type, either all positive or negative. Above will fail for values like (-17, 15) – Deepanshu Oct 21 '16 at 12:53
0

I met the problem too and my solution is using hashMap .The python version is the following:

  def findRepeatNumber(lists):
      hashMap = {}
      for i in xrange(len(lists)):
          if lists[i] in hashMap:
              return lists[i]
          else: 
              hashMap[lists[i]]=i+1
      return
timlentse
  • 195
  • 2
  • 11
0

It is possible only if you have a specific data. Eg all numbers are of a small range. Then you could store repeat info in the source array not affecting the whole scanning and analyzing process.

Simplified example: You know that all the numbers are smaller than 100, then you can mark repeat count for a number using extra zeroes, like put 900 instead of 9 when 9 is occurred twice.

It is easy when NumMax-NumMin

http://www.geeksforgeeks.org/find-the-maximum-repeating-number-in-ok-time/

Den Roman
  • 548
  • 7
  • 10
0

This is impossible without knowing any restricted rules about the input array, either that the Memory complexity would have some dependency on the input size or that the time complexity is gonna be higher.

The 2 answers above are infact the best answers for getting near what you have asked, one's trade off is Time where the second trade off is in Memory, but you cant have it run in O(n) time and O(1) complexity in SOME UNKNOWN INPUT ARRAY.

Ofek Ron
  • 8,354
  • 13
  • 55
  • 103
-1
public static string RepeatedNumber()
    {
        int[] input = {66, 23, 34, 0, 5, 4};
        int[] indexer = {0,0,0,0,0,0}
        var found = 0;
        for (int i = 0; i < input.Length; i++)
        {
            var toFind = input[i];
            for (int j = 0; j < input.Length; j++)
            {
                if (input[j] == toFind && (indexer[j] == 1))
                {
                    found = input[j];
                }
                else if (input[j] == toFind)
                {
                    indexer[j] = 1;
                }
            }

        }


    return $"most repeated item in the array is {found}";

}

Smi.Pol
  • 27
  • 1
  • 6
-4

You can do this

#include<iostream.h>
#include<conio.h>
#include<stdio.h>
void main ()
{
    clrscr();
    int array[5],rep=0;
    for(int i=1; i<=5; i++)
    {
        cout<<"enter elements"<<endl;
        cin>>array[i];
    }
    for(i=1; i<=5; i++)
    {
        if(array[i]==array[i+1])
        {
            rep=array[i];
        }
    }
    cout<<" repeat value is"<<rep;
    getch();
}
peterm
  • 91,357
  • 15
  • 148
  • 157