5

我有两个排序列表,都是非递减顺序。例如,我有一个带元素的排序链表,[2,3,4,5,6,7...]另一个带元素的链表[5,6,7,8,9...]

我需要在两个列表中找到所有常见元素。我知道我可以使用 for 循环和嵌套循环来迭代所有匹配项以找到相同的两个元素。但是,是否有另一种运行时间小于 的方法来做到这一点O(n^2)

4

4 回答 4

10

您可以在 O(n) 时间内完成。伪代码:

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
于 2013-10-02T03:16:06.083 回答
1

其实你可以做得更好一点:

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)
于 2014-01-05T16:11:41.363 回答
0

将第一个列表转换为HashSet; 然后遍历第二个列表,检查每个元素是否在HashSet.

于 2013-10-02T03:14:37.420 回答
0

在主循环中,从两个列表中获取第一个元素并进行比较。如果它们不相等,则扫描具有较少元素的列表,直到它等于或大于另一个循环的元素。如果它相等,这意味着你找到了一个共同的元素。依次读取两个列表,直到通过公共元素。继续主循环。这种方法的复杂度是 O(n+m)。

于 2013-10-02T03:19:52.020 回答