【问题标题】:Runtime Error in "Removing loop from Linked List"“从链接列表中删除循环”中的运行时错误
【发布时间】:2020-10-22 09:55:22
【问题描述】:

我正在尝试以下代码挑战:

给你一个 N 个节点的链表。任务是从链表中删除循环(如果存在)。

注意:C是最后一个节点所连接的节点的位置。如果为0则没有循环。

示例 1:

输入:

N = 3
value[] = {1,3,4}
C = 2

输出: 1

说明:在第一个测试用例中 N = 3.有节点的链表 给出 N = 3。这里,x = 2 表示最后一个节点与 xth 连接 链表的节点。因此,有 存在循环。

示例 2:

输入:

N = 4
value[] = {1,8,3,4}
C = 0

输出: 1

解释: N = 4 和 x = 0,其中 表示 lastNode->next = NULL,因此 链表不包含 任何循环。

你的任务:

你的任务是完成函数removeLoop()。该函数的唯一参数是链表的头指针。只需删除列表中的循环(如果存在),而无需从列表中断开任何节点。如果您的代码正确,驱动程序代码将打印 1。

预期时间复杂度: O(n)

预期的辅助空间: O(1)

约束:

1 <= N <= 104

我的代码:

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

def removeLoop(head):
    slow = fast = head
    while fast!=None and fast.next!=None:
        slow = slow.next
        fast = fast.next.next
        if slow==fast:
            x = slow
    temp = head
    while x.next!=temp.next:
        x = x.next
        temp = temp.next
    x.next = None
    return head

我收到运行时错误。谁能告诉我为什么?

【问题讨论】:

    标签: python algorithm linked-list


    【解决方案1】:

    有几个问题:

    • 当列表没有循环时,则x在处未定义

        while x.next!=temp.next:
      
    • 当列表有循环时,第一个循环永远不会退出。

    • 当循环包括所有个节点(“尾”链接回第一个节点),那么这段代码将断开头节点和第二个节点之间的链接,这显然是错误的。这是一个边界情况,需要单独的解决方案。

    前两个问题深入到缩进问题。第二个while 循环应仅在检测到循环时执行。最简单的方法是将其与return 语句一起移动到检测到循环的if 内:

    def removeLoop(head):
        slow = fast = head
        while fast!=None and fast.next!=None:
            slow = slow.next
            fast = fast.next.next
            if slow==fast:
                if slow == head:  # special case
                    # find the "tail" node
                    while slow.next != head:
                        slow = slow.next
                else:
                    while slow.next != head.next:
                        slow = slow.next
                        head = head.next
                slow.next = None
                return
    

    据我了解,不需要返回任何值,因此无需返回head

    示例运行

    这是用一些样板代码完成的代码,并运行以下问题:

    N = 5
    value[] = {7,58,36,34,16}
    C = 1
    

    所以这表示下面的列表有一个循环:

    7 → 58 → 36
    ↑         ↓
    16   ←   34     
    

    removeLoop 函数将删除 16 和 7 之间的链接。

    class Node:
        def __init__(self, val):
            self.val = val
            self.next = None
    
        def print(self):
            node = self
            for _ in range(10):
                if not node:
                    break
                print(node.val, end=" ")
                node = node.next
            print("..." if node else "")
    
    def createLinkedList(values, cycle_start_index):
        # create all nodes
        nodes = [Node(val) for val in values]
        for i, node in enumerate(nodes):
            if i:  # link node from previous
                nodes[i-1].next = node
        if cycle_start_index > 0:  # create the cycle
            nodes[-1].next = nodes[cycle_start_index-1]  # 1-based index
        return nodes[0]
    
    def removeLoop(head):
        slow = fast = head
        while fast!=None and fast.next!=None:
            slow = slow.next
            fast = fast.next.next
            if slow==fast:
                if slow == head:  # special case
                    # find the "tail" node
                    while slow.next != head:
                        slow = slow.next
                else:
                    while slow.next != head.next:
                        slow = slow.next
                        head = head.next
                slow.next = None
                return
    
    # demo
    lst = createLinkedList([7, 58, 36, 34, 16], 1)
    lst.print()  # 7 58 36 34 16 58 36 34 16 58 ...
    removeLoop(lst)
    lst.print()  # 7 58 36 34 16 
    

    【讨论】:

    • 理解您的逻辑先生,但输入失败 - 输入:5 7 58 36 34 16 1 它的正确输出是:1 而您的代码的输出是:0 为什么? @trincot
    • 我现在明白,当你说输出应该是 1 时,这不是关于 removeLoop 函数,而是关于测试运行器。当输入描述一个完整的循环(将尾部链接回头部)时,我确实看到了一个问题。我已经相应地更新了我的答案。
    • 你检查了吗?有什么反馈吗?
    • 对不起,我无法回复先生。是的,代码有效。非常感谢!
    猜你喜欢
    • 2021-07-25
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多