美文网首页
双指针 5 (环形链表 II leetcode 142)

双指针 5 (环形链表 II leetcode 142)

作者: Sisyphus235 | 来源:发表于2023-01-31 21:56 被阅读0次

    思想

    双指针算法不仅应用于链表,在数组等数据结构中也有广泛应用。
    核心思路是指向问题中的关键节点,根据问题的上下文逻辑变换位置,最终解决问题。

    实例

    环形链表 II leetcode 142

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

    输入:
    head: ListNode,一个链表

    输出:
    ListNode,如果链表中无环返回 None,有环则返回环的开始节点。

    举例:
    当 head = [3,2,0,-4], [2,0,-4] 成环时,返回环开始的节点 2。

    关键点

    核心是判断是否有环,并寻找到环开始的位置。
    (1)判断环
    使用两个指针,快的步长为 2,慢的步长为 1,当快的到达末端前,如果和慢的相遇,存在环。
    (2)环开始的位置

    head ----> start - \
                 /     meet
                |         |
                 \       /
                   - - -  
    

    slow 和 fast 分别从 head 出发,经过了环开始位置 start,在 meet 处相遇。
    此时 slow 行进距离为 head -> start -> meet,fast 形近距离为 head -> start -> meet --[n 圈]--> meet。 设 head -> start = a
    start -> meet = b,环长度 c,fast 在相遇前饶了 n 圈。
    slow 距离 = a + b,fast 距离 = a + b + nc
    fast 行进距离是 slow 的 2 倍,a + b + nc = 2(a + b) => a + b = nc => a = nc - b
    如果从 meet 和 head 用相同步速前进,当 head 处前进 a 到达 start 的时候,meet 处前进了 nc - b 也到达了 start,这样就找到了环的起始点。

    编码

    class ListNode:
        def __init__(self, val=0, next=None):
            self.val = val
            self.next = next
    
    
    def linked_list_cycle_ii(head: ListNode) -> ListNode:
        # 初始位置都在 head
        slow = fast = head
        # fast 步速 2,slow 步速 1,判断是否有环
        while fast is not None and fast.next is not None:
            slow = slow.next
            fast = fast.next.next
            # 存在环,寻找环初始节点
            if slow == fast:
                start = head
                while start != fast:
                    start = start.next
                    fast = fast.next
                return start
        return None
    

    相关

    双指针 0
    双指针 1
    双指针 2
    双指针 3
    双指针 4

    相关文章

      网友评论

          本文标题:双指针 5 (环形链表 II leetcode 142)

          本文链接:https://www.haomeiwen.com/subject/iambhdtx.html