“从链接列表中删除循环”中的运行时错误

Posted

技术标签:

【中文标题】“从链接列表中删除循环”中的运行时错误【英文标题】: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

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

【问题讨论】:

【参考方案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 函数,而是关于测试运行器。当输入描述一个完整的循环(将尾部链接回头部)时,我确实看到了一个问题。我已经相应地更新了我的答案。 你检查了吗?有什么反馈吗? 对不起,我无法回复先生。是的,代码有效。非常感谢!

以上是关于“从链接列表中删除循环”中的运行时错误的主要内容,如果未能解决你的问题,请参考以下文章

运行时错误中的“值不在预期范围内”是啥意思?

Crystal 报告 2010 中的运行时错误

Android设备中的运行时错误

OGS HPC 集群中的 Perl 运行时错误

多线程导致Qt中的运行时错误

Access 中的运行时错误 3011