[劍指Offer] 22_連結串列中導數第K個節點
阿新 • • 發佈:2019-01-13
題目
輸入一個連結串列,輸出該連結串列中倒數第k個節點。為了符合大多數人的習慣,本題從1開始
計數,即連結串列的尾節點是倒數第1個節點。
例:
一個連結串列有6個節點,從頭節點開始,它們的值依次是1->2->3->4->5->6
倒數第3個節點,是值為4的節點。
思路
- 完成功能很簡單,雙指標遍歷連結串列,快指標比慢指標快K個節點,當快指標為None時,慢指標即為倒數第K個節點。
- 時間複雜度:O(n)
- 空間複雜度:O(1)
- 在此給出一個比較單純的解法,遍歷一次連結串列記錄長度,計算出是正數第幾個,再度遍歷。
- 時間複雜度:O(n),雖然都是O(n),此解法需要遍歷2次,係數顯然是大於思路1的
- 空間複雜度:O(1)
程式碼
思路1:時間複雜度:O(n),空間複雜度:O(1)
def kth_node_from_end(head, k):
"""
:param head: head of listnode
:param k: kth from end
:return: node
"""
if head:
slow = fast = head
else:
raise Exception('EMPTY INPUT')
for i in range (k):
if fast:
fast = fast.next
else:
raise Exception("K Out Of Range")
while fast:
fast = fast.next
slow = slow.next
return slow
思考
正如書上所說,這道題考察重點還是在防範異常輸入上。
- head is None,如果此時K>0,會出現None.next報錯
- K大於連結串列長度,在fast node 先走的迴圈中就會出現None.next
- 關於迴圈次數的,由於Python數字時沒有長度限制的,因此不會出現
附上LeetCode題目,供檢驗功能性。
LeetCode 19. 刪除連結串列的倒數第N個節點
題目
給定一個連結串列,刪除連結串列的倒數第 n 個節點,並且返回連結串列的頭結點。
示例:
給定一個連結串列: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,連結串列變為 1->2->3->5.
說明:
給定的 n 保證是有效的。
進階:
你能嘗試使用一趟掃描實現嗎?
程式碼
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
fast = slow = head
for i in range(n):
fast = fast.next
if not fast:
return slow.next
while fast.next:
slow = slow.next
fast = fast.next
slow.next = slow.next.next
return head