“从链接列表中删除循环”中的运行时错误
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 函数,而是关于测试运行器。当输入描述一个完整的循环(将尾部链接回头部)时,我确实看到了一个问题。我已经相应地更新了我的答案。 你检查了吗?有什么反馈吗? 对不起,我无法回复先生。是的,代码有效。非常感谢!以上是关于“从链接列表中删除循环”中的运行时错误的主要内容,如果未能解决你的问题,请参考以下文章