floyd's cycle detect算法

本文深入分析了一段用于查找整数数组中重复数字的Python脚本,探讨了其工作原理,包括使用“乌龟和兔子”算法在循环中找到交点的方法,并解释了算法背后的数学原理。此外,文章还指出该脚本的潜在问题,如对错误数据的处理不足,并提供了改进思路。

今天在网上看到一个python脚本,用来求一串数字中重复得那个数字,具体看这里:http://www.keithschwarz.com/interesting/code/?dir=find-duplicate

他得程序是

def findArrayDuplicate(array):
    assert len(array) > 0

    # The "tortoise and hare" step.  We start at the end of the array and try
    # to find an intersection point in the cycle.
    slow = len(array) - 1
    fast = len(array) - 1

    # Keep advancing 'slow' by one step and 'fast' by two steps until they
    # meet inside the loop.
    while True:
        slow = array[slow]
        fast = array[array[fast]]
#        print 'step: ', 's :',slow, ' f: ', fast

        if slow == fast:
#            print 'slow: ',slow
            break

    # Start up another pointer from the end of the array and march it forward
    # until it hits the pointer inside the array.
    finder = len(array) - 1
    while True:
        slow   = array[slow]
        finder = array[finder]

        # If the two hit, the intersection index is the duplicate element.
        if slow == finder:
            return slow

思路就是根据f(i)=A(i)这个函数,将问题抽象成一个闭环求交点得问题。不过我有点疑问,第一个while还好理解,第二while在我看来好像有死循环得可能。另外,只要是有限个数得数组,根据其抽象都会形成一个环,比如[0,1,3,2], ...f(3)=2, f(2)=3...., so, 这个程序对错误数据毫不容错。


ps。上面是我想错了,第二个while那么做是有理论依据的, 如下:

关于找到找到环的入口点的问题,当fast若与slow相遇时,slow肯定没有走遍历完链表,而fast已经在环内循环了n圈(1<=n)。假设slow走了s步,则fast走了2s步(fast步数还等于s 加上在环上多转的n圈),设环长为r,则:

2s = s + nr

则: s = nr

设整个链表长L,入口环与相遇点距离为x,起点到环入口点的距离为a。

a + x = nr
a + x = (n-1) r + r = (n-1)r + L - a
a = (n-1)r + (L - a  - x) 

(L – a – x)为相遇点到环入口点的距离,由此可知,从链表头到环入口点等于(n-1)循环内环+相遇点到环入口点,于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。


<think>首先,用户的问题是:“快速检测环路的技术”,意思是“快速检测环路的技术”。我需要用中文回答这个问题。 我的回答应该包括: 1. 解释快速检测环路的技术。 2. 在回答末尾,必须输出“§§相关问题§§”,然后列出3-5个相关问题。 3. 第一行必须是“§§相关问题§§”,不能换行分散。意思是,输出“§§相关问题§§”后直接列出问题,不要换行或分隔。 示例格式显示: - 先回答问题(可能包括代码)。 - 然后输出“§§相关问题§§”,紧接着是相关问题列表,用数字点表示。 所以,我的回答结构: - 首先,提供关于快速检测环路的技术的信息。 - 然后,输出“§§相关问题§§”。 - 紧接着,列出3-5个相关问题,每个问题以数字点开头(如1. ···)。 主题是“快速检测环路的技术”。在计算机科学中,这通常指的是在图中检测循环(cycle)的技术,比如在图论或链表中检测环。 常见的检测环路的技术包括: - 在链表中:使用快慢指针(Floyd's cycle-finding algorithm)。 - 在图中:使用深度优先搜索(DFS)或广度优先搜索(BFS)来检测环。 - 其他方法如使用并查集(Union-Find)或拓扑排序。 我应该专注于快速检测的方法,所以Floyd's tortoise and hare algorithm是一个经典例子。 既然用户提到了“技术”,我可以简要解释并给出代码示例,就像示例中那样。 用户说“请使用中文回答问题”,所以我必须用中文写所有内容。 现在,构建回答: 1. **回答部分**:解释快速检测环路的技术。例如: - 在链表中,使用快慢指针。 - 在图中,使用DFS。 我可以给出一个简单的代码示例,比如在Python中实现快慢指针。 2. **相关问题部分**:在回答后,输出“§§相关问题§§”,然后列出3-5个相关问题。问题应该基于用户的问题和我的回答。 相关问题示例: 1. 如何优化环路检测算法? 2. 在图中检测环路的其他方法有哪些? 3. 环路检测在现实世界中的应用是什么? 4. 快慢指针算法的时间复杂度是多少? 5. 如何处理大型图中的环路检测? 确保问题数量在3到5个之间。 最后,输出必须严格符合:第一行是“§§相关问题§§”,然后直接是问题列表,没有换行分散。意思是,输出应该是连续的,比如: §§相关问题§§ 1. ··· 2. ··· 3. ··· 没有额外的空格或换行在“§§相关问题§§”之前或之后,除了在问题列表中。 现在,写回答。</think>快速检测环路的技术在计算机科学中常用于图论或链表操作,以高效识别是否存在循环结构。核心方法包括: - **快慢指针算法Floyd's cycle-finding)**:适用于链表或线性结构。使用两个指针,一个移动速度快(如每次两步),另一个慢(每次一步)。如果存在环,快指针最终会追上慢指针。 ```python def has_cycle(head): if not head: return False slow = head fast = head.next while fast and fast.next: if slow == fast: return True # 检测到环 slow = slow.next fast = fast.next.next return False # 无环 ``` - **深度优先搜索(DFS)**:适用于图结构。遍历时维护访问状态(visited),如果遇到已访问但未完成的节点,则存在环。 ```python def dfs_detect_cycle(graph, node, visited, recursion_stack): visited.add(node) recursion_stack.add(node) for neighbor in graph[node]: if neighbor not in visited: if dfs_detect_cycle(graph, neighbor, visited, recursion_stack): return True elif neighbor in recursion_stack: return True # 检测到环 recursion_stack.remove(node) return False ``` - **并查集(Union-Find)**:用于无向图,在连接节点时检查是否形成环。 这些技术的时间复杂度通常为O(n)(n为节点数),确保高效性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值