11

I got this question for an exam:

Given an integer array find the first number which is not repeating in array using O(N) time complexity and O(1) space complexity.

I couldn't think of any solution. I know I can iterate over the array and maintain a linkedhashmap which will store both array element and number of times it appears and then in the end I have to search hashmap to find that number. Space complexity is greater than O(1) but I couldn't think of other solution.

I also read problem carefully and the said that max size of array would be 1million. I think if we can create a custom hashmap which will utilise an fixed size array of 1 million size then this can be achieved in O(1) space complexity as in that case storage required would be constant but nore sure if I am correct. Please let me know if there is any other solution.

Anton Savin
  • 40,838
  • 8
  • 54
  • 90
anonymous
  • 1,920
  • 2
  • 20
  • 30
  • 3
    Maybe it's referring to non repeating consecutive numbers, in which case you only have to compare a number to the previous one? It seems to trivial like that, but it's just a quick idea. – tibtof Jun 08 '15 at 14:11
  • 5
    I dont think just because you use a fixed sized Collection, it means the space complexity is 1... – Codebender Jun 08 '15 at 14:11
  • can it be assumed the array is sorted? – nafas Jun 08 '15 at 14:12
  • 1
    @AbishekManoharan fix size collection has space complexity of 1 – nafas Jun 08 '15 at 14:12
  • 1
    Something is wrong with the statement you provided. **That** task can't be solved with O(N) time and O(1) space. – user3707125 Jun 08 '15 at 14:14
  • 1
    If a max size of input is defined, then asymptotical complexity becomes meaningless because you can always allocate enough memory according to the limit and always do enough operations to qualify both time and space complexity as constant. If max input is ignored, then fixed size container is not a possible solution. – eerorika Jun 08 '15 at 14:14
  • 2
    @nafas No, if collection size is N, then obviously it's not O(1) size complexity, but O(N). – Adam Stelmaszczyk Jun 08 '15 at 14:15
  • Now suppose instead of integer array I have a string with letters from A-Z all caps and I have to find first non-repeating chars then I could maintain one fixed size map of char to integer and then iterate over the array and fill the map. In the end I can iterate over the map to find the charachter. In that scenario space complexity is O(1). as size of map is constant so why I can't allocate a array of 1million size and use it in custom hashmap and have O(1) complexity here. – anonymous Jun 08 '15 at 14:22
  • @anonymous O(1) should mean we have a constant space for any given input. In your case you will need 1 million size for 1 million and 2 million size for 2 million. hence it is O(N) space complexity. Also, iterating over the map for each input means your time complexity is higher than O(N) too. – Codebender Jun 08 '15 at 14:26
  • 5
    Please post the exact problem statement. Sometimes they try to trick you and it is more simple then you think. – NathanOliver Jun 08 '15 at 14:40
  • Yes, please provide the original problem statement. It will be easier for us to answer then. – skrtbhtngr Jun 08 '15 at 14:47
  • @AdamStelmaszczyk why not, for example space complexity of bubble sort is O(1) , regardless of the size of the collection. – nafas Jun 08 '15 at 14:49
  • 1
    Are the numbers all in the range 1 .. arraySize? If so, it's (surprisingly) possible to find all duplicates (not *non-*duplicates) in O(n) time and O(1) space, by cleverly reusing the array itself: see caf's and my answers [here](http://stackoverflow.com/questions/5739024/finding-duplicates-in-on-time-and-o1-space). – j_random_hacker Jun 08 '15 at 14:58
  • 1
    @nafas because bubble sort is done in-place, and doesn't use any space other than that already occupied by the collection being sorted. – Alexander Revo Jun 08 '15 at 15:28
  • *@AlexanderRevo bubble sort uses constant number of **extra** space(s) ( it still has that temporary space if you remember correctly) . thus as long as creating new spaces is a constant number then space complexity is O(1) – nafas Jun 08 '15 at 15:30
  • The obvious solution would be to sort the array, and then look for adjacent duplicates in the sorted array. Sort is normally O(n lg n), or worse, but you can sort integers in O(n), using a radix sort. (Whether this will be faster than the classical algorithms is another question, but it is O(1).) – James Kanze Jun 08 '15 at 16:20
  • possible duplicate of [Accenture interview question - find the only unpaired element in the array](http://stackoverflow.com/questions/2644179/accenture-interview-question-find-the-only-unpaired-element-in-the-array) – Brent Washburne Jun 09 '15 at 00:11
  • Looks similar to this (which actually has an answer): https://stackoverflow.com/questions/7370978/how-can-we-find-a-repeated-number-in-array-in-on-time-and-o1-space-complexit – dhke Oct 10 '15 at 14:23
  • You don't need the number of times. So for performance, the distribution of singletons is important. An equally distributed random int (32 bit) in 1 Mio. ints will lead to many, many singletons, so you have to go to the whole array only one, two, maybe 3 times. If almost all values occur more than 2 times, storing the duplicates in a HashMap might help. Then you can look them up fast. If every value is only 1 or 2 times in the map, most of them 2 times, that would be a possible, pathologic input. – user unknown Feb 04 '18 at 12:42

4 Answers4

1

If there are exactly TWO (or in multiples of 2) entries for all elements except one element, which will be non-repeating, you can use XOR operator.

Example:

int x=arr[0];
for(i=1;i<1000;i++)
  x^=a[i];
printf("Non-repeating: %d",x);

Any number XORed with itself is 0. So, if any number appears twice it will be 0 in the overall XOR result, thus leaving only the non-repeating number in x.

Note: If you have 1 million numbers, the variable to store the XOR result must be large enough.

skrtbhtngr
  • 2,223
  • 23
  • 29
  • 1
    -1, sorry. This answer is correct, but it doesn't answer the OP's question. The first sentence amounts to "If this were a different problem, you could use the XOR operator." – ruakh Jun 08 '15 at 14:14
  • 6
    this doesn't seem to solve the problem, what is array is [1,2,3,1]? how is that gonna answer 2? – nafas Jun 08 '15 at 14:14
  • @nafas: Please read the first line of my answer carefully. I have just provided the idea, actual implementation of the idea according to the question's requirements is up to the solver himself! – skrtbhtngr Jun 08 '15 at 14:16
  • @skrtbhtngr sorry mate, given the condition it can work – nafas Jun 08 '15 at 14:17
  • I didn't understand this. Even if there are exactly two entries for all elements except one, it will do a binary XOR and screwup the value right?? Can you please elaborate more??? – Codebender Jun 08 '15 at 14:21
  • 2
    Suppose the array is [11,26,35,26,11], then XORing all the elements will give the answer: 35. That is a property of the XOR operation. XOR operation return 0 if its operands are equal, thus, leaving only the non-repeating element. – skrtbhtngr Jun 08 '15 at 14:24
  • Got it.. thanks... But your code wont work for input with 0 in the array... Right??? – Codebender Jun 08 '15 at 14:30
  • Right @AbishekManoharan. This is just an example code snippet. It has much room for input validation and optimization. – skrtbhtngr Jun 08 '15 at 14:40
  • @AbishekManoharan: Why do you think this code wouldn't work for zero? (I mean, don't get me wrong -- this code is fundamentally wrong, because it doesn't support examples like the one nafas gave -- but none of its problems has to do with support for zero.) – ruakh Jun 08 '15 at 16:29
  • @ruakh, You are right, it will work for zeros are well given "_If there are exactly TWO (or in multiples of 2) entries for all elements except one element_" – Codebender Jun 09 '15 at 03:10
1

To find first non-repeating number in given integer array

UPDATE: Found a better solution. I think we can solve it in O(n) time complexity using an additional data structure such as HashMap. Iterate through the array, and put the element as key and the element's index position in array as the value in the map. if the key already exists, can either remove the key-value pair or just set the value to -1. Once the entire array is traversed, then we can get the keySet() from the hashmap, and then find the key which has lowest value(ignore -1). so this would be Time Complexity: O(N) Space Complexity: O(N)

Old solution: We can solve this by, creating another array which is obtained by sorting the given array. This would take O(nlogn) time. then we can iterate through each element in given input array, try to find the element & compare with next element in the sorted array, if repeated continue for the next element in given array, if not repeated, then we found the first non-repeating element in given input array of integers.

time complexity: O(nlogn)
space complexity: O(n)

P.S: I am sorry, hadn't read all the comments, James Kanze has already provided this solution in comments, credits to him.

src3369
  • 1,839
  • 2
  • 17
  • 18
0

I did this using PowerShell

[int[]]$arr = @(6,2,1,2,6,1,7)

$Collection = New-Object 'System.Collections.Generic.list[System.Object]'
$props=[ordered]@{"Index"=9999;"Value"=9999;"Numcount"=9999}
$record = New-Object -TypeName psobject -Property $props
$Collection.Add($record) #This record is added to do a Contains operation 
#for future items to be added in the $collection object

for($i =0;$i -lt $arr.Length;$i++)
{
if($i -eq 0)
{
    $props=[ordered]@{"Index"=$i;"Value"=$arr[$i];"Numcount"=1}
    $record = New-Object -TypeName psobject -Property $props
    $Collection.Add($record)
}


elseif($Collection.value.Contains($arr[$i]))
{

    $count = ($Collection | ?{$_.Value -eq $arr[$i]} | select -First `
1).Numcount
    ($Collection | ?{$_.Value -eq $arr[$i]} | select -First 1).Numcount = `
$count+1
}
else
{
    $props=[ordered]@{"Index"=$i;"Value"=$arr[$i];"Numcount"= 1}
    $record = New-Object -TypeName psobject -Property $props
    $Collection.Add($record)
}

}
Write-Output "The first non repeating number in the array is listed below"
$Collection | Sort-Object Numcount -Descending | ?{$_.Numcount -eq 1} | 
Select -First 1

OUTPUT:-
The first non repeating number in the array is listed below
Index Value Numcount
----- ----- --------
6     7        1
SatishK
  • 1
  • 1
-4

I believe the trick to solve the problem is :

max size of array would be 1million

since :

O(1) space means that the memory required by the algorithm is constant

then space complexity will automatically becomes O(1) given the constant 1M. NOTE. 1M is still a constant number even though its a really large number. thus we only need to concentrate on time complexity.

Using a LinkedHashMap we can add a new element with O(1) and retrieve element with O(1) thus updating an entry will take O(1) too. it also preserves the order. therefore, we can find the earliest entry

then the problem will become simple in two steps:

  1. build up the LinkedHashMap --> O(n)
  2. find the earliest number which its count is 0 --> O(n)

each of the above steps requires O(n) thus overall time complexity is O(2n) = O(n).

nafas
  • 5,283
  • 3
  • 29
  • 57
  • 1
    That way you can make *any* algorithm perform in constant space. I doubt that this "trick" is what is expected here. Not in an exam assignment. – JensG Jun 08 '15 at 15:11
  • @JensG if there is an upper bound then you can make the space complexity contant – nafas Jun 08 '15 at 15:12
  • 2
    You reply to the wrong point. The point is that there is very likely no trick question in an exam. And even if there is one, not such a stupid one. – JensG Jun 08 '15 at 15:13
  • @JensG I would have imagined the aim of this question is to understand what is the true meaning of space complexity. so all you need to know that 1M is still a constant number – nafas Jun 08 '15 at 15:20
  • 1
    This is O(n) size complexity. True meaning of constant space complexity is that algorithm's space requirement doesn't depend on input size. If your algorithm uses, say, 4 bytes to process 100 elements, it should use the same 4 bytes to process 100 billion elements in order to be said to have constant space complexity. – Alexander Revo Jun 08 '15 at 15:32
  • @AlexanderRevo for the given problem it will always use 1M * (whatever bytes Map of 1M Entires is). since the assumption is the size will not go over 1M – nafas Jun 08 '15 at 15:39
  • 3
    @nafas... Complexity is determined for an algorithm .. not for a problem... Just because this problem has an upper limit of 1M doesn't mean your algorithm is having a o(1) complexity... – Codebender Jun 08 '15 at 15:44