Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better way to find matches in two sorted lists than using for loops?

I have two sorted lists, both in non-decreasing order. For example, I have one sorted linked list with elements [2,3,4,5,6,7...] and the other one with elements [5,6,7,8,9...].

I need to find all common elements in both lists. I know I can use a for loop and a nested loop to iterate all matches to find the same two elements. However, is there another way to do this that has running time less than O(n^2)?

like image 634
codeedoc Avatar asked Oct 02 '13 03:10

codeedoc


People also ask

How do you compare two sorted lists?

We can club the Python sort() method with the == operator to compare two lists. Python sort() method is used to sort the input lists with a purpose that if the two input lists are equal, then the elements would reside at the same index positions.

Which search is best for sorted array?

If we know nothing about the distribution of key values, then we have just proved that binary search is the best algorithm available for searching a sorted array.


2 Answers

You can do it in O(n) time. Pseudocode:

a = list1.first
b = list2.first
repeat:
    if a == b:
        output a
        a = list1.next
        b = list2.next
    elif a < b:
        a = list1.next
    else
        b = list2.next
until either list has no more elements
like image 128
Blorgbeard Avatar answered Nov 03 '22 01:11

Blorgbeard


Actually you can do a little better:

def dropWhile(ls, cond):
    if cond(ls[0]): return dropWhile(ls[1:], cond)
    return ls

def bisect(ls, v):
    """
    Finds largest i s.t. ls[i]<=v and returns it.
    If no such i exists it returns -1.
    Runs in O(log n)
    """
    pass

def find_commons(ls1, ls2, ret):
    if not (ls1 or ls2): return
    i = bisect(ls2, ls1[0])
    if i<0: find_commons(ls2, ls1[1:], ret)
    elif ls2[i]==ls1[0]:
        ret.append(ls1[0])
        trim = lambda ls: dropWhile(lambda x: x==ls1[0], ls)
        find_commons(trim(ls1), trim(ls2), ret)
    else: find_commons(ls2[i+1:], ls1, ret)
like image 37
user2070206 Avatar answered Nov 03 '22 02:11

user2070206