簡體   English   中英

從鏈表末尾刪除第 k 個節點

[英]remove kth node from end of linked list

我正在嘗試從鏈表的END中刪除第kth元素。 這是我的代碼

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

但這不起作用並打印出鏈表中從0到9的所有值。為什么會這樣? 如果要刪除的節點是我通過檢查trailing is None ,那么我更新head = head.next 我正在改變head成為下一個節點。 我可以在此更新后返回head並且head = removeKthNodeFromEnd(head, k)的結果將為我提供所需的輸出,但為什么我不能以其他方式執行而不返回任何內容? 例如,在我的解決方案中,我可以去掉第一個節點和最后一個節點之間的任何元素,包括最后一個節點,並且工作得很好。 原始頭得到更新,節點被刪除。 但是當嘗試更新頭節點head = head.next時,它不起作用。

我實現這一目標的一種方法是執行以下操作...

if trailing is None:
  head.value = head.next.value
  head.next = head.next.next

但是為什么我必須使用這些值? 對我來說,這似乎與

if trailing is None:
  head = head.next
  head.next = head.next.next

但不起作用

它不起作用,因為該函數中的head本地名稱。 分配給局部變量永遠不會對其他變量做任何事情,即使它們碰巧具有相同的名稱(如全局head )。

當列表只有一個節點時,使用head.value = head.next.value移動鏈表值的“技巧”將不起作用。

一種方法是返回head的(可能修改的)值,並期望調用者將其分配回他們自己的head變量。

所以:

  • removeKthNodeFromEnd確保所有return語句都像return head ,並在最后添加一個return head 簡而言之, removeKthNodeFromEnd應該總是返回head

  • 在主程序中,將調用改為head = removeKthNodeFromEnd(head, 10)

這將解決您的問題。

這里有一些想法可以讓你的代碼更優雅:

  • 創建一個單獨的類來維護鏈表的頭部
  • 改進構造函數,使初始化鏈表更容易
  • 添加迭代器,以便更容易打印鏈表
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)

如果你維護一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM