鍊錶問題 在單鏈表和雙鏈表中刪除倒數第K個節點

2021-08-09 06:26:35 字數 3037 閱讀 4092

【題目】

在單鏈表和雙鏈表中刪除倒數第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 快速找到前一結點,顧名思義,單鏈表只能單向讀取 為什麼市場上單鏈表的使用多餘雙鏈表呢?從儲存結構來看,每個雙鏈表的節點要比單鏈表的節點多乙個指標,...