一、题目描述

判断给定的链表中是否有环。如果有环则返回true,否则返回false。

输入分为两部分,第一部分为链表,第二部分代表是否有环,然后将组成的head头结点传入到函数里面。-1代表无环,其它的数字代表有环,这些参数解释仅仅是为了方便读者自测调试。实际在编程时读入的是链表的头节点。

二、题目解析

双指针的经典题型。

1、定义一个慢指针,一开始指向链表的头节点,每次只会向前移动 1 步。

2、定义一个快指针,一开始指向链表的头节点,每次只会向前移动 2 步。

3、让快慢指针顺着链表同时不断的向后移动,如果快慢指针相遇,说明有环,返回 true;如果快指针访问完毕了所有结点,指向了 null 还没相遇,说明没有环,返回 false。

三、参考代码

// 本题文字版详解请访问下方网站
// https://www.algomooc.com
// 作者:程序员吴师兄
public class Solution {
    public boolean hasCycle(ListNode head) {
        // 1、通过快慢指针的方式,在环中寻找它们的第一次相遇的节点位置

        // 2、定义一个慢指针,每次只会向前移动 1 步
        ListNode slow = head;
        // 3、定义一个快指针,每次只会向前移动 2 步
        ListNode fast = head;

        // 4、如果链表有环,那么无论怎么移动,fast 指向的节点都是有值的
        while (fast != null && fast.next != null) {
            // 慢指针每次只会向前移动 1 步
            slow = slow.next;
            // 快指针每次只会向前移动 2 步
            fast = fast.next.next;

            // 快慢指针相遇,说明有环
            if( slow == fast){
                // 返回 true
                return true;
            } 
        }

        // 没有环,返回 false
        return false;
    }
}