1. 程式人生 > >[劍指Offer] 22_連結串列中導數第K個節點

[劍指Offer] 22_連結串列中導數第K個節點

題目

輸入一個連結串列,輸出該連結串列中倒數第k個節點。為了符合大多數人的習慣,本題從1開始
計數,即連結串列的尾節點是倒數第1個節點。

例:

一個連結串列有6個節點,從頭節點開始,它們的值依次是1->2->3->4->5->6
倒數第3個節點,是值為4的節點。


思路

  1. 完成功能很簡單,雙指標遍歷連結串列,快指標比慢指標快K個節點,當快指標為None時,慢指標即為倒數第K個節點。
    1. 時間複雜度:O(n)
    2. 空間複雜度:O(1)
  2. 在此給出一個比較單純的解法,遍歷一次連結串列記錄長度,計算出是正數第幾個,再度遍歷。
    1. 時間複雜度:O(n),雖然都是O(n),此解法需要遍歷2次,係數顯然是大於思路1的
    2. 空間複雜度: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

思考

正如書上所說,這道題考察重點還是在防範異常輸入上。

  1. head is None,如果此時K>0,會出現None.next報錯
  2. K大於連結串列長度,在fast node 先走的迴圈中就會出現None.next
  3. 關於迴圈次數的,由於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