Simple linear solution:
It can be done in O(n+m)
time (on average) and O(n)
space (n
being the size of the first array, m
being the size of the second array).
set = new empty hash set
for each x in arr2:
set.add(x)
for each x in arr1 in ascending order:
if set.contains(x):
return x
//if here, no duplicates
return null
Slight improvement in memory consumption:
It can be improved to O(min{n,m})
space, by first checking which array is smaller, if the second- do the same algorithm as suggested, otherwise, load into the map (x,i)
- the (element,index) pair, iterate the second list, and find the smallest i
where there is a match, and return it:
Pseudo code for the approach with better memory complexity:
def secondSmaller(arr1,arr2):
set = new empty hash set
for each x in arr2:
set.add(x)
for each x in arr1 in ascending order:
if set.contains(x):
return x
//if here, no duplicates
return null
def firstSmaller(arr1,arr2):
map = new empty hash map
for each x in arr1 with index i:
map.add(x,i)
minimal = infinity
minVal = null
for each x in arr2:
if set.contains(x):
i = map.get(x)
if i < minimal:
minimal = i
minVal = x
return minVal
if arr1.size() > arr2.size():
return secondSmaller(arr1,arr2)
else return firstSmaller(arr1,arr2)
Related thread: How do I calculate the delta (inserted/deleted/moved indexes) of two lists?
As a side note, this is closely correlates to the Element Distinctness Problem, and I doubt it can be done more efficiently than this, due to the lower bounds of element distinctness problem.