[英]Python delete a node in linked list, given just access to that node
This is a LeetCode question, I knew its solution, but wondering about why my code not work. 这是一个LeetCode问题,我知道它的解决方案,但想知道为什么我的代码不起作用。
Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.
编写一个函数以删除单链接列表中的节点(尾部除外),仅授予对该节点的访问权限。
Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function
假设链表为1-> 2-> 3-> 4,并且给了第三个节点值为3,则在调用函数后链表应变为1-> 2-> 4
At first glance, my intution is delete like an array: 乍一看,我的直觉是像数组一样删除:
shift all the node values one front, then delete the tail, here's my implementation and test case: 将所有节点值前移一次,然后删除尾部,这是我的实现和测试用例:
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)
But After deletion, it has two 5 value nodes, the tail was still kept, can anyone please explain to me what's wrong here? 但是删除后,它有两个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
Really appreciate any help. 真的感谢任何帮助。
You were almost there, but are doing way too much work shifting all val
values up one node. 您几乎在那里,但是正在做太多工作,将所有
val
值上移一个节点。 You also failed to clear the last next
reference, which is why you see 5
printed twice . 您也没有清除上一个
next
参考,这就是为什么您看到5
打印两次的原因 。 I'll show you how to solve the problem properly first, then address removing the tail. 我将向您展示如何正确解决该问题,然后解决尾巴问题。
You can indeed solve this puzzle by not deleting the node, just by setting the value
to the next value, and the next
pointer to the node after the next. 您确实可以解决此难题,方法是不删除节点,而只需将
value
设置为下一个值,并将next
指针指向下一个节点即可。 And that is all you need to do, you don't need to touch any of the following nodes. 这是所有你需要做的,你不需要接触任何以下节点。 You'd effectively delete the next node and making this node hold the next value instead:
您将有效地删除下一个节点,并使该节点保留下一个值:
node
|
v
--------- ---------
---> | val: va | ---> | val: vb | ---> ?
--------- ---------
becomes 变成
node
|
v
--------- ---------
---> | val: vb | -+ | val: vb | -> ?
--------- | --------- |
| |
----------------
So the implementation is as simple as: 因此实现很简单:
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
No loop required. 无需循环。
Back to your attempt, note that the last line in your function has no effect. 回到您的尝试,请注意函数的最后一行无效。
node
is a local name in your function, and references the tail ListNode
instance, until you set it to None
instead. node
是函数中的本地名称 ,并引用尾部ListNode
实例, 直到将其设置为None
为止 。
You had this: 你有这个:
node
|
v
-----------
---> | val: tail | ---> None
-----------
and node = None
does this: 并且
node = None
这样做:
node -> None
X
|
v
-----------
---> | val: tail | ---> None
-----------
That incoming reference from the previous node is still there . 从上一个节点传入的引用仍然存在 。
You'd have to track the 'one-but-last' node reference and clear the .next
attribute on that once looping is done: 循环完成后,您必须跟踪“最后一个”节点引用并清除
.next
属性:
while node.next:
node.val = node.next.val
prev, node = node, node.next
# clear reference to tail
prev.next = None
def deleteNode(node):
node.val = node.next.val
node.next = node.next.next
Since you don't have a reference to your current node, you can't delete it. 由于您没有对当前节点的引用,因此无法删除它。 But you do have a ref to your next node.
但是您确实有对下一个节点的引用。 So give your current node the role that your next node previously had, and then the garbage collector will delete your next node, since there are no refs to it left because you overwrote node.next.
因此,为当前节点赋予下一个节点以前的角色,然后垃圾收集器将删除下一个节点,因为由于重写了node.next,因此没有剩余引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.