环路检测· 6 月更文挑战

89 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情

一、题目描述:

给定一个链表,如果它是有环链表,实现一个算法返回环路的开头节点。若环不存在,请返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

示例 1:

img

输入:head = [3,2,0,-4], pos = 1 输出:tail connects to node index 1 解释:链表中有一个环,其尾部连接到第二个节点。 示例 2:

img

输入:head = [1,2], pos = 0 输出:tail connects to node index 0 解释:链表中有一个环,其尾部连接到第一个节点。 示例 3:

img

输入:head = [1], pos = -1 输出:no cycle 解释:链表中没有环。

进阶:

你是否可以不用额外空间解决此题?

来源:力扣(LeetCode) 链接:leetcode.cn/problems/li… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

根据题意可知,当链表中有环时,遍历链表是走不到尽头的。如果遍历到空节点,说明链表无环;那么可以使用快慢指针的方式。

用一快一慢两个指针从链表头开始遍历,快指针每次走2步,慢指针每次走1步;

进入环后,快指针每次会追上慢指针1步,所以若链表有环,快指针一定会追上慢指针;

当两个指针相等时,假设慢指针走了k步,那么快指针一定走了2k步,且此时快指针超过了慢指针若干圈,而且是正好超过整数圈,所以它们才会相遇。则快指针比慢指针多走的这k步,是环中节点个数的整数倍;

这时把其中一个指针挪到链表头部继续遍历,两指针每次走一步,当它们再次相遇时,相遇的节点就是链表环入口

三、AC 代码:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null) {
            return null;
        }
        ListNode slow = head, fast = head;
        while (fast != null) {
            slow = slow.next;
            if (fast.next != null) {
                fast = fast.next.next;
            } else {
                return null;
            }
            if (fast == slow) {
                ListNode ptr = head;
                while (ptr != slow) {
                    ptr = ptr.next;
                    slow = slow.next;
                }
                return ptr;
            }
        }
        return null;
    }
}

四、总结:

掘友们,解题不易,留下个赞或评论再走吧!谢啦~ 💐

希望对你有帮助,期待您找到心意的工作和满意的offer

期待下次再见~

\