zoukankan      html  css  js  c++  java
  • Floyd 判圈算法

    Floyd 判圈算法

    摘自维基百科, LeetCode 上 141题 Linked List Cycle 用到这个, 觉得很有意思. 记录一下. 

    链接: https://zh.wikipedia.org/wiki/Floyd%E5%88%A4%E5%9C%88%E7%AE%97%E6%B3%95

    用于判断链表上是否有环, 并给出环的起点和长度.

    也叫做龟兔赛跑算法, 拥有线性时间复杂度和常数空间复杂度.

    原理:

    1. 判定是否有环: 假设 t 和 h 同时从起点 S 出发, t 的步长是一步, h 的步长是两步, 如果有环, 则 t 与 h 一定会在环上一点相遇, 记为 M.

    2. 环的长度: 如果判定有环, h 不动, t 绕环一圈回到 h, 就是环的长度.

    3. 环的起点: h 仍不动, t 回到起点 S, 这时候 t 按原路径走到 h 的距离, 是环的整数倍. 这时候 t 和 h 同时以相同步长(只能是一步)前进, 相遇处便是环的起点, 记为 P.

    代码:

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def hasCycle(self, head):
            """
            :type head: ListNode
            :rtype: tuple (bool, length, start_node)
            """
            try:
                slow = head.next
                fast = head.next.next
                while slow is not fast:
                    slow = slow.next
                    fast = fast.next.next
                
                slow = slow.next
                length = 1
                while slow is not fast:
                    slow = slow.next
                    length += 1
    
                slow = head
                while slow is not fast:
                    slow = slow.next
                    fast = fast.next
    
                 return True, length, slow          
            except:
                return False, None, None
  • 相关阅读:
    codeforces 980A Links and Pearls
    zoj 3640 Help Me Escape
    sgu 495 Kids and Prizes
    poj 3071 Football
    hdu 3853 LOOPS
    hdu 4035 Maze
    hdu 4405 Aeroplane chess
    poj 2096 Collecting Bugs
    scu 4444 Travel
    zoj 3870 Team Formation
  • 原文地址:https://www.cnblogs.com/senjougahara/p/6502019.html
Copyright © 2011-2022 走看看