Given an array of integers where some numbers repeat 1 time, some numbers repeat 2 times and only one number repeats 3 times, how do you find the number that repeat 3 times. Using hash was not allowed. Complexity of algorithm should be O(n)
-
http://stackoverflow.com/questions/555744/algorithm-to-find-two-repeated-numbers-in-an-array-without-sorting – AVB Mar 23 '10 at 04:37
-
@Chris Dodd - I'm somewhat inclined to agree with you, but based on what polygenelubricants posted, I suspect there is a smart way to do it. I can't figure it out, but I'm looking forward to finding out what the answer is! – David Johnstone Mar 23 '10 at 05:16
-
1@SS by using hash, does this mean that you can't use maps/dictionaries or just that you can't use a hash function on each number to figure it out? – Justin Peel Mar 23 '10 at 05:19
-
Wow, you're really sticking to your title huh. – Jon Limjap Mar 23 '10 at 06:06
-
Duplicate + needs homework tag ? – Paul R Mar 23 '10 at 06:16
-
@ all the question is complete, i am still trying to figure out the solution. this is not a homework problem, i am preparing for interview – Supriya Sane Mar 23 '10 at 17:09
-
1Why wouldn't you be allowed to use hashing? The hashing solution is the simplest correct answer to the problem which satisfies the constraints. – Juliet Mar 23 '10 at 18:05
-
1This is the same as question as here: http://discuss.joelonsoftware.com/default.asp?interview.11.790844 Nobody knows how to solve it there either. – David Johnstone Mar 23 '10 at 22:32
-
In the joel on software discussion there is actually one additional requirement: `O(1)` space, and that's even harder. – Matthieu M. Mar 24 '10 at 07:44
11 Answers
I assume the array is not sorted, or similary, repeats of a number don't appear in one contiguous run. Otherwise, the problem is really trivial: just scan the array once with a window of size 3, and if each number in that window is the same, then that's the number that repeats 3 times in one contiguous run.
If the repeats are scattered, then the problem becomes more interesting.
Since this is homework, I will only give you a hint.
This problem is a cousin of where you're given an array of unsorted integers, and all numbers appear an even number of times, except one that appears an odd number of times.
That number can be found quite easily in O(N)
by performing an exclusive-or of all the numbers in the array; the result is the number that appears an odd number of times.
The reason why this works is that x xor x = 0
.
So for example, 3 xor 4 xor 7 xor 0 xor 4 xor 0 xor 3 = 7
.

- 376,812
- 128
- 561
- 623
-
Thanks polygenelubricants for your hint. I have to figure out how to differentiate between the numbers that repeat once and thrice. – Supriya Sane Mar 23 '10 at 04:46
-
10I'm interested in how exactly you plan on using xor, since this time you have more numbers that can appear an odd number of times (some numbers can appear a single time, then there's the one that appears 3 times). – IVlad Mar 23 '10 at 06:42
-
@stubbscroll: The question is worded like a homework problem would be. It's abstract, yet unusually specific; it fits the pattern "Given X, find Y"; and it demands "Complexity of algorithm should be O(n)". – Gabe Mar 23 '10 at 12:00
-
2Since x + 2x = 3x this problem is considerably harder than the simple XOR case in base 2. Looking forward to seeing your proof polygene ... – Ian Mercer Mar 25 '10 at 15:53
-
3
-
@SupriyaSane , nikhil - Polygene answered the question , thats nice of him, and the question out here is not Its homework or not . polygenelubricants is kind enough to help you out with what he has, so the tones should be humble enough to ask. polygenelubricants - Any idea if there are multiple numbers as such ? coz XOR will fail in that case. – bhuvin Mar 28 '13 at 09:18
-
1This is an incorrect solution. XOR would have worked if the number to find appears only once *or* thrice, not both. – Bugaboo Mar 06 '17 at 19:28
Use radix sort (which is linear in the number of bits required to specify the integers), then scan for the triplet.

- 17,763
- 5
- 68
- 136
Here's an answer that assumes max(A) is reasonably small, where A is the input array:
int ValidCount(int[] a, int[] b, int i, int n) {
int num = a[i];
int ret = 0;
if (b[3*num] >= 0 && b[3*num] < n && a[b[3*num]] == num) ret++;
if (b[3*num+1] >= 0 && b[3*num+1] < n && a[b[3*num+1]] == num) ret++;
if (b[3*num+1] >= 0 && b[3*num+2] < n && a[b[3*num+2]] == num) ret++;
b[3*num+ret] = i;
return ++ret;
}
int threerep(int[] A, int aSize) {
int *B = malloc(sizeof(int) * 3 * max(A, aSize)); /* Problematic if max(A) is large */
/* Note that we don't rely on B being initialized before use */
for(int i = 0; i < aSize; i++) {
if (ValidCount(A, B, i, aSize) == 3) return A[i];
}
return ERROR_NO_ANSWER;
}

- 31
- 1
Essentially, the problem is to compute the mode of the array. This solution works "ONLY" if the array range is [0,n-1]. Putting the solution here since the problem does not put a clause of the range.
- Assume that 'n' is the size of the array
- Scan the array and mark A[A[i]]=A[A[i]]+n -----> 1st pass
- Divide each array element by 'n', i.e A[i]=A[i]/n ----> 2nd pass
- The element with the maximum value from the 2nd pass is the answer.
This is O(n) with O(1) space (but with a range clause).
I am not aware of any algorithm to compute the mode in O(n),O(1) with no clauses on the range.

- 973
- 1
- 17
- 36
-
You can also normalize the array input to 0,n-1 and your solution will be slightly more generic to handle the arrays with p,q ranges where q=p <= n. – sharjeel Aug 25 '13 at 17:34
i dont see what all the fuss is about: using python 2.6 and a simple function which goes over the list, counts occurances, once it finds a number that occurs 3 times, returns it.
>>> def find3(l):
from collections import defaultdict
d = defaultdict(int)
for n in l:
d[n]+=1
if d[n] == 3:
return n
>>> print find3([1,1,1,2,3,4,5,6,7])
1
>>> print find3([1,1,2,3,4,5,6,7,5])
None
>>> print find3([1,1,2,3,4,5,6,7,5,4,5,5])
5

- 41,843
- 24
- 85
- 131
-
python has the benefit of an associative array, which is similar to using bucket sort or radix sort as suggested in other answers. it runs in O(n) but also uses space(n) – shak Sep 09 '13 at 13:29
-
@shak Great, and I am sure you will also tell me why you added this comment almost a year after I provided this answer? Maybe you want to add your own answer? Maybe you want to provide a link to what you just mentioned? – Inbar Rose Sep 09 '13 at 13:33
Bugaoo's algorithm looks neat that is quoted below. Actually, we can generalize it by doing an extra pass before "1st pass" to find min(A) and max(A) and another extra pass to move each element in A to the range of min(A) and max(A), i.e., A[0]-min(A). After "1st pass" and "2nd pass" (note that we should mod the elements by max(A)-min(A) instead of n), we could add min(A) to the duplicated number found at last.
Essentially, the problem is to compute the mode of the array. This solution works "ONLY" if the array range is [0,n-1]. Putting the solution here since the problem does not put a clause of the range. Assume that 'n' is the size of the arrayScan the array and mark A[A[i]]=A[A[i]]+n -----> 1st pass Divide each array element by 'n', i.e A[i]=A[i]/n ----> 2nd pass The element with the maximum value from the 2nd pass is the answer. This is O(n) with O(1) space (but with a range clause). I am not aware of any algorithm to compute the mode in O(n),O(1) with no clauses on the range.

- 315
- 2
- 2
Well all I can think of is this but I'm sure your prof is looking for a tricky equation that will solve this in 1 scan. You can do it in 2 scans which is O(n) assuming that you can create a 2nd array of size (0 to max number in 1st array). Scan once, find max number in array. Create 2nd array of that size. Iterate over 1st array again using 2nd array as buckets to increment a count for each element in 1st array. Once you increment a bucket to 3 that's your solution. Not the best but it would work in some cases.

- 1,289
- 2
- 9
- 20
If you know min and max of the integer sequence and min>=0, create an array [min, max] filled with zeros. Scan the given array and if i occures, increment i-th position by one. After finishing you have frequency table in the second array, where the array position points to an integer.

- 1,410
- 12
- 35
-
-
algorithmist: there should be an option of using the sparse array (http://en.wikipedia.org/wiki/Sparse_array) then, like linked list. – D_K Mar 25 '10 at 09:47
-
How do you propose to implement a sparse array with constant-time operations without hashing? – user287792 Mar 25 '10 at 17:14
-
int count[2^32]; for x in input: count[x] = 0; // delete this loop if you can assume ram is cleared to 0. for x in input: count[x]++; for x in input: if count[x] == 3: return x
Please excuse the mix of languages :-) Also, this is really stupid to have an array that can be indexed with any integer - you can do it on a 64bit system and it does meet the requirements.

- 5,687
- 1
- 23
- 31
-
What if this is in some language like Python or Scheme that allows arbitrary sized integers? – Gabe Mar 23 '10 at 17:39
-
This works in theory (assuming only 32 bit ints), but you're never (well, maybe not NEVER, but you get the point) going to be able to declare an array of 4 294 967 296 ints. – IVlad Mar 23 '10 at 17:51
-
2-1: I've heard of trading space for time, but sweet jesus! A 32-bit int = 4 bytes, so a 2^32 int array is about 4 GB. The interview will end very quickly if someone wrote code like this. – Juliet Mar 23 '10 at 17:57
-
You can declare the array on 64bit machine with 64bit OS. Other suggested scanning the input to determine the required size, while I just punted since it could be 4GB anyway. If you malloc it, it will not be zeroed and will be fast. – phkahler Mar 24 '10 at 13:34
-
2@juliet - please point to a valid solution that works before you reject one because you don't like it. – phkahler Mar 24 '10 at 13:38
-
The inverted page tables used by 64-bit machines are based on hashing, so that's a bit of a dodge. – user287792 Mar 25 '10 at 19:59
This Algorithm looks pretty good one.... but i don't know its implementation.. Only pseudocode.... If any1 good try his hands on code(C programming), then please post it....
PseudoCode goes here... Take two bitset arrays of size n. We can use this array to count upto three occurrences i.e. if array1[i] = 1 and array2[i] = 1, then it means we have three occurrences of i+1th element.
for each integer 'i' if(array2[i] == 1) array2[i] = 0, array1[i] = 1; else array2[i] = 1;
for each element K in the arrays if (array1[k] && array2[k]) return k;
Complexity = O(n) and Space = 2n bits.

- 5,165
- 16
- 56
- 72
I'll present a solution that works in general general, such that one number occurs m
times and others n
times.
We need an operator that cancels out n
occurrences of a integer but keeps m
occurrences. If we convert each number to its binary representation, and for each bit position, count the number of times that this bit is set, the value will be a multiple of n
for all numbers that occur n
times, plus 0
or m
for the corresponding bit of the lone integer.
If we then take modulo n
of each of these counts, and divide by m
, the result is the value of the corresponding bit position for the lone integer. All that's left is to convert the binary result to decimal formal.
For example, given array = [3, -4, 3, 3], m = 1 and n = 3:
Binary of 3 = 011
Binary of -4 (2s complement) = 11111111111111111111111111111100
Bit 0: 3 % 3 = 0
Bit 1: 3 % 3 = 0
Bit 2 through 32: 1 % 3 = 1
The result is -4

- 21,927
- 20
- 110
- 219