[英]remove kth node from end of linked list
I am trying to remove the kth
element from the END of a linked list.我正在尝试从链表的END中删除第
kth
元素。 Here is my code这是我的代码
class LinkedList:
def __init__(self, value):
self.value = value
self.next = None
def removeKthNodeFromEnd(head, k):
if k == 0 or head is None:
return
temp = head
while temp is not None and k > 1:
temp = temp.next
k -= 1
if temp is None or k > 1:
return head
trailing = None
leading = head
while temp.next is not None:
trailing = leading
leading = leading.next
temp = temp.next
if trailing is None:
head = head.next
else:
trailing.next = leading.next
head = LinkedList(0)
head.next = LinkedList(1)
head.next.next = LinkedList(2)
head.next.next.next = LinkedList(3)
head.next.next.next.next = LinkedList(4)
head.next.next.next.next.next = LinkedList(5)
head.next.next.next.next.next.next = LinkedList(6)
head.next.next.next.next.next.next.next = LinkedList(7)
head.next.next.next.next.next.next.next.next = LinkedList(8)
head.next.next.next.next.next.next.next.next.next = LinkedList(9)
removeKthNodeFromEnd(head, 10)
while head is not None:
print(head.value)
head = head.next
But this does not work and prints out all the values in the linked list from 0 to 9. Why is this the case?但这不起作用并打印出链表中从0到9的所有值。为什么会这样? If the node to delete is the head node which I check by checking
trailing is None
, then I update head = head.next
.如果要删除的节点是我通过检查
trailing is None
,那么我更新head = head.next
。 I am changing head
to be the next node.我正在改变
head
成为下一个节点。 I can return head
after this update and the result of head = removeKthNodeFromEnd(head, k)
will give me the desired output but why can't I do it the other way without returning anything?我可以在此更新后返回
head
并且head = removeKthNodeFromEnd(head, k)
的结果将为我提供所需的输出,但为什么我不能以其他方式执行而不返回任何内容? For instance in my solution I can get rid of any element in between the first and last node including the last and works just fine.例如,在我的解决方案中,我可以去掉第一个节点和最后一个节点之间的任何元素,包括最后一个节点,并且工作得很好。 The original head gets updated and node gets removed.
原始头得到更新,节点被删除。 But when trying to update the head node
head = head.next
it does not work.但是当尝试更新头节点
head = head.next
时,它不起作用。
One way I achieved this is by doing the following...我实现这一目标的一种方法是执行以下操作...
if trailing is None:
head.value = head.next.value
head.next = head.next.next
But why must I use the values?但是为什么我必须使用这些值? To me this seems the same as
对我来说,这似乎与
if trailing is None:
head = head.next
head.next = head.next.next
but does not work但不起作用
It doesn't work because head
in that function is a local name.它不起作用,因为该函数中的
head
是本地名称。 Assigning to a local variable never does anything to other variables, even not when they happen to have the same name (like the global head
).分配给局部变量永远不会对其他变量做任何事情,即使它们碰巧具有相同的名称(如全局
head
)。
The "trick" you have by moving a linked list value with head.value = head.next.value
will not work when the list only has one node.当列表只有一个节点时,使用
head.value = head.next.value
移动链表值的“技巧”将不起作用。
One way to do this, is to return the (potentially modified) value of head
, and expect the caller to assign this back to their own head
variable.一种方法是返回
head
的(可能修改的)值,并期望调用者将其分配回他们自己的head
变量。
So:所以:
in removeKthNodeFromEnd
make sure all return
statements are like return head
, and that you add a return head
at the very end.在
removeKthNodeFromEnd
确保所有return
语句都像return head
,并在最后添加一个return head
。 In short, removeKthNodeFromEnd
should always return head
.简而言之,
removeKthNodeFromEnd
应该总是返回head
。
in the main program, change the call to head = removeKthNodeFromEnd(head, 10)
在主程序中,将调用改为
head = removeKthNodeFromEnd(head, 10)
That will solve your issue.这将解决您的问题。
Here are some ideas to make your code more elegant:这里有一些想法可以让你的代码更优雅:
class Node: # renamed
def __init__(self, value, nxt=None):
self.value = value
self.next = nxt # is now an argument
class LinkedList: # added
def __init__(self, *values):
self.head = None
if values: # populate the list with values
for value in reversed(values):
self.push_front(value)
def push_front(self, value):
self.head = Node(value, self.head)
def __iter__(self):
node = self.head
while node:
yield node.value
node = node.next
def removeKthNodeFromEnd(self, k):
if k <= 0:
return
temp = self.head
for _ in range(k):
if not temp: # k is out of range
return
temp = temp.next
if temp:
trailing = self.head
while temp.next:
trailing = trailing.next
temp = temp.next
trailing.next = trailing.next.next
else:
self.head = self.head.next
lst = LinkedList(*range(10))
print(*lst)
lst.removeKthNodeFromEnd(0)
print(*lst)
And if you maintain a size
attribute, you can do:如果你维护一个
size
属性,你可以这样做:
class LinkedList: # added
def __init__(self, *values):
self.head = None
self.size = 0
if values:
for value in reversed(values):
self.push_front(value)
def push_front(self, value):
self.head = Node(value, self.head)
self.size += 1
def __iter__(self):
node = self.head
while node:
yield node.value
node = node.next
def removeAt(self, k):
if 1 < k <= self.size:
trailing = self.head
for _ in range(k - 2):
trailing = trailing.next
trailing.next = trailing.next.next
elif 1 == k <= self.size:
self.head = self.head.next
def removeKthNodeFromEnd(self, k):
self.removeAt(self.size + 1 - k)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.