One of my friend was asked this question in an interview -
Two passes through the array will suffice.
1st pass: add every item in the shorter list to a hashmap (dict in python). 2nd pass: for each item in the longer list, check if key exist in hashmap (O(1) search time). If not, that key is the unique entry.
Total time complexity: O(2n) = O(n)
Depending on the language you are using, it might have a built in way to do the array differences. PHP does http://ca3.php.net/array_diff
Technically, you can do it in constant time, since the arrays (and values within them) are limited. For the generalized problem, we have to make out something trickier.
Here's a linear-time solution.
First, we should build a hash based on one array. Value lookup in a hash table takes O(1 + k/n) comparisons [1], where k is the length of hash table. Thus iteration over the first array (that contains n elements) and lookups for each value takes O(n+k).
Then we iterate the other one, looking up for each element in the hash. When an element is not found -- that's unique one from the other array. (O(n+k) again). Then we iterate hash to look for the second unique element (O(k)).
Total time is O(n+k). Since it doesn't make sense to let k be more than n, it's the linear solution.
Perl code for that:
sub unique
{
my ($arr, $brr) = @_;
my %hash = map{$_ => 1} @$arr;
%hash{$_}-- for @$brr;
return grep {$_} keys %hash;
}
int[] a = {1, 2, 3, 5};
int[] b = {1, 2, 3, 5, 6};
HashSet set = new HashSet();
for (int o : b) {
set.add(o);
}
for (int p : a) {
if (set.contains(p)) {
set.remove(p);
}
}
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Log.d("TAG", " " + iterator.next());
}
Make sets A, B of the arrays a,b respectively. A \ B gives you the additional integer in A. B \ A gives you the additional integer in B.
If either one of these operations returns an empty set, then the additional integer is in the array twice. You find this out when constructing the set: adding a duplicate integer to the set does not increase the set's size.
Put each element of the first array into a hash. For each item in the second array, if it's already in the hash, remove it, else add it. At the end you have a hash with two keys, which are your unique elements.
Simple verison in Ruby
def unique(a,b)
h={}
a.each do |ax|
h[ax]=true
end
b.each do |bx|
if h[bx]
h.delete(bx)
else
h[bx]=true
end
end
h.keys
end
With a little more Ruby personality, but still in the universe where we can't simply do (a | b) - (a & b)
or a.to_set ^ b.to_set
:
def unique(a,b)
h = {}
a.each do |ax|
h[ax] = true
end
b.each do |bx|
h.delete(bx) or h[bx] = true
end
h.keys
end