Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if a number only appears once in an array

This is kind of a homework question, I've been thinking about it for quite a while, and came up with a couple of solutions but I think a better one exists.

What's the fastest way to determine if there is an element (int) in the array that appears only once? Any element can appear any number of times. {3, 1, 4, 1, 4, 3} will return false while {3, 1, 4, 1, 4, 1} would return true (3 appears once).

We are only allowed to use things we already learned (all the basics, recursion, oop, searching and sorting algos, including quicksort) so making a hash table is not an option.

So far the best practical solution I came up with is sorting it using quicksort then going through it ( O(nlogn) ), the best unpractical solution I came up with is making a big array the size of all possible int values and then using it's place similar to a hash table (but that array is WAY too big to actually implement) ( O(n) )

Is there another (practical) way to do this in O(n) time?

EDIT: just got an answer from the TA, the suggested O(n) solution that I heard about was an unpractical one (the same or similar to what I suggested) and hence they told us not to use it. I'm 99% sure now that the best practical answer (without hash tables) is O(nlogn) time.

like image 546
kostia Avatar asked May 15 '13 15:05

kostia


People also ask

How do you check if a number appears twice in an array?

Multiply the array element at that given value (index) with a negative number say -1. If a number have appeared once then the value in the array at that index will be negative else it will be positive if it has appeared twice (-1 * -1 = 1).

How do you find a single number in an array?

The best solution is to use XOR. XOR of all array elements gives us the number with a single occurrence.

How do you know if an array has one or consecutive numbers?

Method 1 (Use Sorting) 1) Sort all the elements. 2) Do a linear scan of the sorted array. If the difference between the current element and the next element is anything other than 1, then return false. If all differences are 1, then return true.


1 Answers

You could use a customised quicksort to find distinct values without iterating over the sorted array afterwards.

When you have chosen a pivot value and are moving through the respective part of the array, IF the value matches the pivot, discard it AND discard the pivot value after you have moved through the part of the array, this would remove duplicates BEFORE the array is eventually sorted.

ie:

Sorting [5, 1, 4, 1, 4, 1]
If you choose the pivot as 4, you'd end up with the 2 sub arrays being:
[1, 1, 1] and [5]

If your pivot is never discarded, it is distinct, if it is discarded do the same process on the sublists. If a sublist has only 1 element, it is distinct.

In this way you can pick up distinct values MUCH earlier.

Edit: Yes this is still bounded by O(nlogn) ( I think ?)

like image 53
Ben Meier Avatar answered Sep 28 '22 09:09

Ben Meier