【问题标题】:Intersection of two linked lists without duplicities没有重复的两个链表的交集
【发布时间】:2021-11-13 22:54:12
【问题描述】:

给定两个排序的链表,结果应该是没有重复的交集。

  • 不允许创建新节点。
  • 结果列表将由原始列表的元素组成。

输入是由空行分隔的两个列表

L1 -> 2 3 3 4 4 4 5

L2 -> 3 4 5 6 7

结果 -> 3 4 5

我在下面有我的解决方案,但是在 IntersectionDestruct 函数中创建了新节点。

有没有什么简单的方法可以改变IntersectionDestruct函数的逻辑,不创建任何新节点?

class Node:
def __init__(self, data, next = None):
    self.data = data
    self.next = next

def PrintLinkedList( p ):
    print( "Result:", end=" " )
    while p!=None:
        print( p.data, end=" " )
        p = p.next
    print(".")

def ReadLinkedList():
    first = None
    last = None
    r = input()
    while r!="":
        row = r.split()
        if len(row)==0:
            break
        for s in row:
            p = Node(int(s),None)
            if first==None:
                first = p
            else:
                last.next = p
            last = p
        r = input()
return first

def LLIntersection(a, b):
    head = tail = None

    while a and b:
        if a.data == b.data:
            if head is None:
                head = Node(a.data, head)
                tail = head
            else:
                tail.next = Node(a.data, tail.next)
                tail = tail.next

            a = a.next
            b = b.next

        # advance the smaller list
        elif a.data < b.data:
            a = a.next
        else:
            b = b.next
    return head    

【问题讨论】:

  • 请修正代码的缩进,例如,在第 2 行。

标签: python-3.x algorithm linked-list


【解决方案1】:

您的解决方案实际上并不能防止重复,如果您在两个列表中都有重复的数字,那么将 a 和 b 一起推进会导致它们再次匹配并且重复出现在结果中。

您应该将它们都提升到一个 数字,以防止任何重复。

然后只需通过将 a 分配给列表并清除其下一个值来重用原始节点,这样它就不会泄漏到现有列表中。

def IntersectionUnique(a, b):
    head = tail = None

    while a and b:
        if a.data == b.data:
            if head is None:
                head = tail = a
            else:
                tail.next = a
                tail = a
            
            # Skip past all duplicates (careful for end of list!)
            while a.next and a.data == a.next.data:
                a = a.next
            while b.next and b.data == b.next.data:
                b = b.next

            # Advance to new values
            a = a.next
            b = b.next
            
            # Clear tail
            tail.next = None

        # advance the smaller list
        elif a.data < b.data:
            a = a.next
        else:
            b = b.next
    return head

由于这会覆盖 a 节点上的下一个值,因此在此之后从 a 遍历列表将得到与使用函数之前相同的结果,直到第一个相交的项目被下一个覆盖,然后将仅是相交值之后。

因此认为它已损坏,仅使用返回值。

【讨论】:

  • 干得好。 Nits:Skip past all duplicates 不是 while 循环所做的:它们前进到最后一个重复。您无需多次设置tail.next:在return 之前设置。您无需在两个列表中都跳过重复项:将外部循环的尾部替换为 while a and a.data == b.data: a = a.next 或更糟。
  • @greybeard 是的,他们前进到最后一个重复以保证前进到新值始终是一个新值 - 因此,跳过所有重复的值。它没有设置tail.next 两次,tail 在这两个点有一个不同的值,第一次设置现有的tail 指向新的Node,然后更新tai​​l 也指向新的Node ,第二次是在新节点上设置next。您可以只推进 a 并多次重复外部循环+比较以推进 b,但这会导致执行流程不太清晰,我正在更新 他们的 代码以使其清楚。
  • 非常感谢 Ashley,此解决方案符合更好的预期结果。
猜你喜欢
  • 2018-05-12
  • 2015-10-16
  • 1970-01-01
  • 2021-12-29
  • 1970-01-01
  • 2020-05-31
  • 1970-01-01
  • 2013-08-29
相关资源
最近更新 更多