Common Elements Of Three Arrays
March 17, 2015
We have another interview question today. There are several different ways to approach this task, so it makes for an interesting exercise:
Given three arrays of integers in non-decreasing order, find all integers common to all three arrays. For instance, given arrays [1,5,10,20,40,80], [6,7,10,20,80,100] and [3,4,15,20,30,70,80,120] the two common integers are 20 and 80. If an integer appears multiple times in each of the arrays, it should appear multiple times in the output, so with input arrays [1,5,5,5], [3,4,5,5,10] and [5,5,10,20] the correct output is [5,5].
Your task is to write a program to solve the interview question. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
My solution is to find shortest two arrays to process biggest one only one time.
This allows for searching for only common integers from the two shortest arrays in bigest one.
Output:
20
80
999
999
Haskell:
There is probably a more concise solution using lists comprehension, but alas it eludes me
Similar solution in SML:
fun intersect (xs, ys) = let
fun loop(out, _, []) = List.rev out
| loop(out, [], _) = List.rev out
| loop(out,left as x::xs, right as y::ys) =
if x < y then loop(out, xs, right)
else if y < x then loop(out, left, ys)
else loop(x::out, xs, ys)
in
loop([], xs, ys)
end
fun nintersect [] = []
| nintersect (xs::xss) = List.foldl intersect xs xss;
[/sourcecode]
Sorry, issue with formatting:
This one is like Scott’s – for each element in the first array, discarding lower elements in the other arrays, moving on to the next element if no match is found. A nice flourish is to use a sentinel element at the end of each array, when a match is found and it’s the sentinel element we break the loop. No other bounds checking is needed:
In Python. This works for an arbitrary number of arrays.
The Python standard library collections.Counter acts like a multi-set, making this problem a one-liner.
for(p=0;p<a.length;p++)
{
for(q=0;q<b.length;q++)
{
if(b[q]==a[p])
{
// System.out.println("matching values found in array a and b:::"+b[q]);
for(r=0;r<c.length;r++)
{
if(c[r]==b[q])
{
common[common_ite]=c[r];
System.out.println("common integer found:::"+common[common_ite]);
common_ite++;
break;
}
//ends for loop r….for c array
}
break;
//end if of b array…
}
//end for loop of q …for b array…
}
//ends main foor loop..of array a…
}
It can be made more efficient by using common array with length of shortest array…use of break is not encouraged…but its fast and in any interview..it maybe helpful in time constraint..
OK, here’s another one, same trick with sentinels. Iterate down all 3 lists, if the current element in list i is less than the current element in list i+1 (mod 3), skip it. If no element is skipped, they must all be the same. Possibly does more comparisons than my other solution, but at least uses INT_MAX properly:
Wrote my own Bag implementation in Python, for the heck of it. Although obviously I should have used collections.Counter :)