链表中环的入口结点-快慢指针-公式详解

举报
yd_248793506 发表于 2024/01/20 17:31:30 2024/01/20
【摘要】 快慢指针算法是一种用于检测链表中是否存在环的经典算法。通过使用两个指针,一个移动速度较快,一个移动速度较慢,可以有效地检测链表中是否存在环,并在相遇时找到环的入口节点。

使用快慢指针检测链表中的环和找到环的入口节点

1. 算法介绍

快慢指针算法是一种用于检测链表中是否存在环的经典算法。通过使用两个指针,一个移动速度较快,一个移动速度较慢,可以有效地检测链表中是否存在环,并在相遇时找到环的入口节点。

2. 算法实现

以下是使用 Java 实现的算法代码:

class ListNode {
    int val;
    ListNode next;

    ListNode(int val) {
        this.val = val;
        this.next = null;
    }
}

public class LinkedListCycle {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;

        // 使用快慢指针检测环
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;

            // 如果相遇,则说明链表中存在环
            if (slow == fast) {
                // 找到环的入口节点
                ListNode entry = head;
                while (entry != slow) {
                    entry = entry.next;
                    slow = slow.next;
                }
                return entry;
            }
        }

        // 如果快指针或快指针的下一个为空,说明链表中不存在环
        return null;
    }
}

3. 示例说明

考虑以下链表示例:

1 -> 2 -> 3 -> 4 -> 5 -> 6
               ^         |
               |         v
               9 <- 8 <- 7

在这个示例中,节点 4 和节点 9 之间形成了一个环。我们使用上述代码进行检测,将得到环的入口节点为 4。

4. 算法原理解释

  • 快慢指针同时从链表头部出发,快指针每次移动两个节点,慢指针每次移动一个节点。
  • 如果链表中存在环,两个指针最终会在环内的某一点相遇。
  • 一旦相遇,我们通过一个额外的指针从链表头部出发,和慢指针一样每次移动一个节点。
  • 当这两个指针再次相遇时,相遇点即为环的入口节点。

让我进一步解释上述方程的含义:

在算法执行的过程中,假设链表头到环的入口点的距离为 a,相遇点到环的入口点的距离为 b,环的长度为 c。当快慢指针相遇时,慢指针走了 a + b 的距离,而快指针走了 a + b + n * c 的距离,其中 n 是快指针在环内走的圈数。

将这个信息代入方程:

2(a + b) = a + b + n·c

整理后得到:

a = (n - 1)·c + (c - b)

这个方程告诉我们,链表头到环的入口点的距离等于快指针在环内多走了 (n-1) * c 步加上慢指针在环内走的剩余距离 (c-b)。换句话说,a 的值可以表示为环的整数倍加上慢指针在环内的剩余距离。

接下来,如果我们使用一个指针从链表头开始,同时以和慢指针相同的速度前进,那么在走了 a 步之后,这个指针将会与慢指针相遇。因为两者的速度相同,它们在环内的相对位置不会发生改变。相遇点即为环的入口点。

希望这一解释能够更清晰地说明为什么在找到环后,再使用一个指针从链表头开始,最终能够在环的入口点与慢指针相遇。

5. 时间复杂度

该算法的时间复杂度为 O(n),其中 n 是链表的长度。

6. 结论

快慢指针算法是一种高效的方法,用于检测链表中是否存在环,并找到环的入口节点。通过掌握这个算法,您可以在解决相关问题时更加灵活地使用链表数据结构。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。