【python鏈表】之快慢指針思想(含實例)

一、快慢指針的概念

快慢指針中的快慢指的是移動的步長,即每次向前移動速度的快慢。例如可以讓快指針每次沿鏈表向前移動2次,慢指針每次向前移動1次。

如果我們要在上圖鏈表中 刪除value爲10的節點,只需要設置兩個指針,每一次移動後,快指針都會比慢指針多走一個節點,這就能形成一個指針間的差值,通過這個差值,來斷開或者鏈接指針域,從而達到需要的結果。

二、快慢指針的應用

2.1 找中間值

思路:

設一個快指針 fast,設一個慢指針slow,假定快指針每次移動速度是慢指針的兩倍,當快指針到達尾部節點指向None時,慢指針則處於鏈表的中間節點,從而確定中間節點的值。

圖示:

在這裏插入圖片描述

slow與fast指針都指向鏈表第一個節點,然後slow每次移動一個指針,fast每次移動兩個指針。

代碼示例:

class ListNode:
    def __init__(self, x, next=None):
        self.val = x
        self.next = next

class Solution:
    def deleteNode(self, head: ListNode):

        slow = head  # 慢指針
        fast = head  # 快指針


        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        print(slow.val)


if __name__ == '__main__':
    a = ListNode(14, ListNode(23, ListNode(10, ListNode(35, ListNode(56, ListNode(59,ListNode(12,)))))))
    obj = Solution()
    Node = obj.deleteNode(a)
    
    
# 結果爲 35

2.2 刪除倒數第n個節點

思路:

1、刪除倒數第n個節點,意味着需要獲得 n-1的指針域以及n的指針域。

2、設置快慢兩個指針,先讓快指針先走n+1步,然後再和慢指針一起走,當快指針爲None時,慢指針剛好停留在 n-1的位置。

圖示:

代碼實例:

# 快慢指針
class ListNode:
    def __init__(self, x, next=None):
        self.val = x
        self.next = next

class Solution:
    def kthToLast(self, head: ListNode, k: int) -> int:

        slow = head  # 慢指針
        fast = head  # 快指針

        while k+1 > 0:
            fast = fast.next
            k -= 1

        while fast.next is not None:
            fast = fast.next
            slow = slow.next
        slow.next = slow.next.next

        while head is not None:
            print(head.val)
            head = head.next

if __name__ == '__main__':
    a = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5,)))))
    obj = Solution()
    Node = obj.kthToLast(a, 2)

    
    # 結果爲 1,2,4,5

2.3 判斷是否爲環狀鏈表

思路:

快慢指針中,因爲每一次移動後,快指針都會比慢指針多走一個節點,所以他們之間在進入環狀鏈表後,不論相隔多少個節點,慢指針總會被快指針趕上並且重合,此時就可以判斷必定有環。

圖示:

如果fast指針遍歷出None,則說明沒有環。

當slow指針和falst指針相同,則說明環有節點。

代碼示例:

class Node:
    def __init__(self, val, next=None):
        self.val = val
        self.next = next

def findbeginofloop(head):
    slow = head  # 慢指針
    fast = head  # 快指針
    if head is None:  # 判斷鏈表是否爲空
        return head

    while fast.next != None and fast.next.next != None:  # fastPtr的下一個節點和下下個節點都不爲空
        slow = slow.next
        fast = fast.next.next
        if slow == fast:  # 兩個指針相遇存在環結構
            print("存在環結構")
            break

if __name__ == "__main__":
    node1 = Node(1)
    node2 = Node(2)
    node3 = Node(3)
    node4 = Node(4)
    node5 = Node(5)
    node1.next = node2
    node2.next = node3
    node3.next = node4
    node4.next = node5
    node5.next = node2
    findbeginofloop(node1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章