【python链表】之快慢指针思想(含实例)

文章目录

    • 一、快慢指针的概念
    • 二、快慢指针的应用
      • 2.1 找中间值
      • 2.2 删除倒数第n个节点
      • 2.3 判断是否为环状链表

一、快慢指针的概念

快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢。例如可以让快指针每次沿链表向前移动2次,慢指针每次向前移动1次。

【python链表】之快慢指针思想(含实例)_第1张图片

如果我们要在上图链表中 删除value为10的节点,只需要设置两个指针,每一次移动后,快指针都会比慢指针多走一个节点,这就能形成一个指针间的差值,通过这个差值,来断开或者链接指针域,从而达到需要的结果。

二、快慢指针的应用

2.1 找中间值

思路:

设一个快指针 fast,设一个慢指针slow,假定快指针每次移动速度是慢指针的两倍,当快指针到达尾部节点指向None时,慢指针则处于链表的中间节点,从而确定中间节点的值。

图示:

【python链表】之快慢指针思想(含实例)_第2张图片

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的位置。

图示:

【python链表】之快慢指针思想(含实例)_第3张图片

代码实例:

# 快慢指针
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 判断是否为环状链表

思路:

快慢指针中,因为每一次移动后,快指针都会比慢指针多走一个节点,所以他们之间在进入环状链表后,不论相隔多少个节点,慢指针总会被快指针赶上并且重合,此时就可以判断必定有环。

图示:

【python链表】之快慢指针思想(含实例)_第4张图片

如果fast指针遍历出None,则说明没有环。

【python链表】之快慢指针思想(含实例)_第5张图片

当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)

你可能感兴趣的:(python链表专栏)