【題目】
在單鏈表和雙鏈表中刪除倒數第k個節點。
要求時間複雜度o(n),空間複雜度o(1)。
【基本思路】
方法一。
從煉表頭開始走到尾,每移動一步,k減1。移動完之後,如果k > 0,說明鍊錶長度不夠k,根本就沒有倒數第k個值,返回頭節點 head;如果k = 0,說明鍊錶的長度等於k,頭節點就是倒數第k個節點,返回 head.next;如果 k < 0,說明鍊錶的長度大於k,再次從頭遍歷鍊錶,這時,每遍歷一步就讓k加1,當 k = 0時,遍歷到的節點就是倒數第k個節點的前乙個節點,之後刪除倒數第k個節點就很容易了。
為什麼這麼做是可行的?因為如果鍊錶長度是n,要刪除倒數第k個節點,顯而易見,第n - k個節點就是倒數第k個節點的前乙個節點。第一次遍歷的完後,k的值變為k - n,第二次遍歷的終止條件是k = 0,顯然,k - n 加上 n - k 等於0,也就是說,k = 0的時候,實際上就是遍歷了n - k個節點。所以當 k = 0時,遍歷到的節點就是倒數第k個節點的前乙個節點。
方法二。
設定兩個指標 fast 、slow,fast先走k步,如果走不到第k步(none節點是可以走到的,但是none節點沒有next,所以只能走到none),說明鍊錶長度不夠k,直接返回head;如果走到第k步,發現該節點是none節點,說明鍊錶的長度等於k,頭節點就是倒數第k個節點,返回 head.next;否則,令 fast 和 slow 開始同步往下移動,直到 fast 移動到最後乙個節點(不包含none),此時slow就是倒數第 k 個節點的前乙個節點,之後刪除倒數第k個節點就很容易了。
單鏈表和雙鏈表刪除倒數第k個節點的原理是一樣的,只不過是雙鏈表刪除節點的時候稍微複雜一點。
【**實現】
#python3.5
#單鏈表
class
node:
def__init__
(self, val=none):
self.val = val
self.next = none
defremovelastkthnode1
(head, k):
if head == none
or k < 1:
return head
cur = head
while cur != none:
k -= 1
cur = cur.next
if k == 0:
return head.next
elif k < 0:
cur = head
while k+1 != 0:
cur = cur.next
k += 1
cur.next = cur.next.next
return head
defremovelastkthnode2
(head, k):
if head == none
or k < 1:
return head
fast = slow = head
while k > 0:
k -= 1
if fast == none:
return head
else:
fast = fast.next
if fast == none:
return head.next
while fast.next != none:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return head
#雙鏈表
class
doublenode:
def__init__
(self, val = none):
self.val = val
self.pre = none
self.next = none
defremovelastkthdoublenode1
(head, k):
if head == none
or k < 1:
return head
cur = head
while cur != none:
k -= 1
cur = cur.next
if k == 0:
head = head.next
head.pre = none
elif k < 0:
cur = head
while k+1 != 0:
k += 1
cur = cur.next
cur.next = cur.next.next
if cur.next != none:
cur.next.pre = cur
return head
defremovelastkthdoublenode2
(head, k):
if head == none
or k < 1:
return head
fast = slow = head
while k > 0:
k -= 1
if fast != none:
fast = fast.next
else:
return head
if fast == none:
head = head.next
head.pre = none
else:
while fast.next != none:
slow = slow.next
fast = fast.next
slow.next = slow.next.next
if slow.next != none:
slow.next.pre = slow
return head
單鏈表 雙鏈表 迴圈鍊錶總結
1.單鏈表 為公升序鍊錶,value按公升序排列 include include typedef struct node node 最好放在標頭檔案中 node sll creat int sll length node p node sll del node head,int value void...
鍊錶的實現 單鏈表 雙鏈表
鍊錶知識的引入 對於之前我們接觸到的陣列知識,要想儲存多個物件,首先想到的一定是物件陣列。但是陣列是乙個長度固定的線性結構,一旦內容不足或者過多,都會在成記憶體資源的浪費,由此引入鍊錶充分解決資源浪費問題。class node private屬性需要設定getter setter方法 public ...
單鏈表和雙鏈表
單鏈表 單鏈表只有乙個指向下一結點的指標,也就是只能next 雙鏈表 雙鏈表除了有乙個指向下一結點的指標外,還有乙個指向前一結點的指標,可以通過prev 快速找到前一結點,顧名思義,單鏈表只能單向讀取 為什麼市場上單鏈表的使用多餘雙鏈表呢?從儲存結構來看,每個雙鏈表的節點要比單鏈表的節點多乙個指標,...