栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java常见算法---弗洛伊德算法(环的相关判断)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java常见算法---弗洛伊德算法(环的相关判断)

Java常见算法---弗洛伊德算法(环的相关判断)
  • 弗洛伊德算法
    • 1. 判断是否有环
    • 2. 判断环的入口在哪

弗洛伊德算法 1. 判断是否有环

定义快慢指针,快指针每次走两步,慢指针每次走一步,如果快指针走到了链表的结尾都没有相遇,则无环;如果快慢指针在链表的除了头结点的地方相遇了,则证明有环。

public ListNode hasCycle(ListNode head) {
    // 只有一个节点
    if (head == null || head.next == null) return false;
    // 定义快慢指针
    ListNode fast = head, slow = head;
    // 快指针速度是慢指针二倍
    while (fast != null && fast.next != null) {
        fast = fast.next.next;
        slow = slow.next;
        // 如果在链表某处相遇
        if (fast == slow) return true;
    }
    // 快指针走到链表结尾,返回false
    return false;
}
2. 判断环的入口在哪

快慢指针会在环内相遇,那么如何找到环的入口呢?
在这里需要定义第三个指针finder。当快慢指针在环内相遇时,helper指针从链表头开始和slow指针一起走,当helper指针和slow指针相遇时,即为环的入口。
为什么helper与slow一定能在环的入口处相遇?

我们首先假设:从链表到环的入口长度为m,当快慢指针相遇时,慢指针走了n步,则快指针走了2n步。现在我们单独看环内。

在环内,快指针走了2n-m步,慢指针走了n-m步。快指针比慢指针多走了2n-m-(n-m) = n步。从图中我们可以看到,这个n,实际上就是环的周长的倍数。即如果指针站在入口,走n步,一定还是回到原点,即还在入口处。
此时,慢指针从入口进,走了n-m步,因此,再走m步,慢指针能回到入口处。而这个m刚好就是链表从头结点到环入口的长度。因此,当快慢指针相遇时,定义一个helper指针和slow指针一起走,走m步,helper指针和slow指针就在环的入口处相遇了。
模板题 [LeetCode]287. 寻找重复数(java实现)

class Solution {
    public int findDuplicate(int[] nums) {
        int fast = 0, slow = 0;
        while(true) {
            fast = nums[nums[fast]];
            slow = nums[slow];
            if(slow == fast) {
                fast = 0;
                while(nums[slow] != nums[fast]) {
                    fast = nums[fast];
                    slow = nums[slow];
                }
                return nums[slow];
            }
        }
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/352197.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号