[英]Python: How to delete ONLY node in a singly-linked list in O(1) time
我已經閱讀了以下帖子,但他們沒有回答我的問題。
這篇文章接近解釋。 @Rishikesh Raje投票最多的回答是,刪除單鏈接列表中的最后一個節點是
[...]通常是不可能的。
為什么通常不可能,而不僅僅是“不可能”? 我的問題既涉及理論本身,又適用於Python? 這個問題是給C的。
此外,我的另一個問題是鏈表只有一個節點的情況,這也使其成為最后一個節點。
背景:我正在LeetCode上解決此問題 。 盡管它不要求刪除最后一種情況,但我嘗試過,但由於某些我無法查明的功能而似乎無法獲得。 這里的一些方向將不勝感激。 我添加了一種打印值以進行調試的方法。
這是問題:
編寫一個函數以刪除單鏈接列表中的節點(尾部除外),僅授予對該節點的訪問權限。
假設鏈表為1-> 2-> 3-> 4,並且給您第三個節點的值為3,則在調用函數后鏈表應變為1-> 2-> 4。
我的代碼可以達到所需的結果1-> 2-> 4:
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
nextNode = node.next
if nextNode:
node.val = nextNode.val
node.next = nextNode.next
else:
node = None
def listToString(self, head):
string = ""
while head:
string += str(head.val) + "\n"
head = head.next
return string
head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(3)
head.next.next.next = ListNode(4)
solution = Solution()
print(solution.listToString(head))
print('-'*10)
node = head.next.next
solution.deleteNode(node)
print(solution.listToString(head))
運行這個給我:
1
2
3
4
----------
1
2
4
但是當我將底部更改為:
head = ListNode(1)
solution = Solution()
print(solution.listToString(head))
print('-'*10)
node = head
solution.deleteNode(head)
print(solution.listToString(head))
我懂了
1
----------
1
問題是:為什么不打印1
而不打印None
? 請注意,此鏈接列表只有一個節點(這意味着它是最后一個節點),這就是傳遞給函數的內容。 能做到嗎 如果是這樣,我應該做哪些修改?
引用列表的頭節點的函數可以刪除頭之后的任何元素,但是無法刪除頭。
如果您考慮一下,這應該很明顯。 無論您做什么,呼叫者仍然會參考傳入的標頭。
但這本身並不是對鏈表的限制,而僅僅是對API的限制。 使用不同的API,這根本不是不可能的:
引用對擁有頭節點的引用的“列表句柄”對象進行引用的函數可以刪除頭節點,如下所示:
handle.head = handle.head.next
引用頭節點的引用的函數(例如C Node **
)不能直接用Python編寫,但是在可以的語言中,就像使用列表句柄一樣容易:
*head = (*head)->next
列表句柄實際上可以很簡單:
class LinkedList:
def __init__(self, head=None):
self.head = head
但是通常您實際上希望將其用於某些用途,例如,向其添加insert
, delete
, append
等方法,甚至可以存儲長度。 (但是,請注意,這種設計可能會破壞尾部共享,因為兩個不同的列表具有不同的頭部但尾部相同,因為現在您可以通過一個LinkedList
句柄更改列表的一部分,而另一個則不知道這樣做了。)
或者,引用頭節點並返回新頭的函數也可以刪除頭:
return head.next
讓我們更詳細地解決這個問題:
def deleteNode(head, node):
if head == node:
return None
ptr = head
while ptr and ptr.next != node:
ptr = ptr.next
if ptr.next == node:
ptr.next = node.next
return head
需要一些錯誤處理,但是如果遵循規則,它將起作用:
head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(3)
head.next.next.next = ListNode(4)
# This goes from 1->2->3->4 to 1->2->4
head = deleteNode(head, head.next.next)
# And this goes to 2->4
head = deleteNode(head, head)
而且很顯然,如果將其更改為搜索值而不是節點,則同樣的事情起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.