这是一个LeetCode问题,我知道它的解决方案,但想知道为什么我的代码不起作用。
编写一个函数来删除单链表中的节点(尾部除外),只允许访问该节点。
假设链表是1 - > 2 - > 3 - > 4,您将获得值为3的第三个节点,链表应为1 - > 2 - > 4调用你的函数后
乍一看,我的直觉就像数组一样被删除:
将所有节点值移到前面,然后删除尾部,这是我的实现和测试用例:
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node4 = ListNode(4)
node5 = ListNode(5)
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node5
def deleteNode(node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
while node.next:
node.val = node.next.val
node = node.next
node = None
deleteNode(node4)
但删除后,它有两个5个值节点,尾部仍然保留,有人可以向我解释这里有什么问题吗?
deleteNode(node4)
node1.val
Out[162]: 1
node1.next.val
Out[163]: 2
node1.next.next.val
Out[164]: 3
node1.next.next.next.val
Out[165]: 5
node1.next.next.next.next.val
Out[166]: 5
非常感谢任何帮助。
答案 0 :(得分:8)
你几乎就在那里,但正在做太多工作,将所有 val
值移到一个节点上。您也无法清除上一个next
引用,这就是为什么您看到5
打印两次的原因。我将首先向您展示如何正确解决问题,然后解决尾部问题。
你可以通过 not 删除节点来解决这个难题,只需将value
设置为下一个值,然后将next
指针指向下一个节点即可。这是您需要做的所有,您不需要触摸以下任何节点。您可以有效地删除下一个节点,并使此节点保留下一个值:
node
|
v
--------- ---------
---> | val: va | ---> | val: vb | ---> ?
--------- ---------
变为
node
|
v
--------- ---------
---> | val: vb | -+ | val: vb | -> ?
--------- | --------- |
| |
----------------
因此实现非常简单:
def deleteNode(node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
不需要循环。
回到您的尝试,请注意您的功能中的最后一行无效。 node
是您函数中的本地名称,并引用尾ListNode
实例,直到将其设置为None
。
你有这个:
node
|
v
-----------
---> | val: tail | ---> None
-----------
和node = None
执行此操作:
node -> None
X
|
v
-----------
---> | val: tail | ---> None
-----------
来自前一节点的传入引用仍然存在。
你必须跟踪一个但最后一个'节点引用并在完成循环后清除.next
属性:
while node.next:
node.val = node.next.val
prev, node = node, node.next
# clear reference to tail
prev.next = None
答案 1 :(得分:1)
def deleteNode(node):
node.val = node.next.val
node.next = node.next.next
由于您没有对当前节点的引用,因此无法将其删除。 但是你确实有一个参考你的下一个节点。 因此,为您的当前节点提供下一个节点以前的角色, 然后垃圾收集器将删除你的下一个节点,因为你没有写任何refs,因为你覆盖了node.next。