【面试题 02.08】 环路检测

题目

题目链接
给定一个有环链表,实现一个算法返回环路的开头节点。
有环链表的定义:在链表中某个节点的next元素指向在它前面出现过的节点,则表明该链表存在环路。
示例 1:

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

示例 2:

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

示例 3:

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

实现思路

利用快慢指针求解。
慢指针每次走一步,快指针每次走两步,在快慢指针都不为null时,如果快慢指针相遇,则一定有环,否则没环,确定相遇位置。
慢指针原地不动,快指针回到起点,快慢指针同时出发一次一步,知道快慢指针再次相遇,相遇的节点就是环的入口。
细节如图所示:
请输入图片描述

代码如下


/**
 * Definition for singly-linked list.
 * class ListNode {
 * int val;
 * ListNode next;
 * ListNode(int x) {
 * val = x;
 * next = null;
 * }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        //啥也没有也不能有环
        if (head == null) return null;
        //快慢指针 快指针一次走两格 慢指针一次走一格 如果两者相遇则一定有环
        ListNode fast = head;
        ListNode low = head;
        //判断是否为环 走完此循环若fast等于low则一定有环
        while (fast != null && low != null) {
            if (fast.next == null) {
                return null;
            }
            fast = fast.next.next;
            low = low.next;
            if (low == fast) {
                break;
            }
        }
        System.out.println(low.val);
        System.out.println(fast.val);
        //两者不相等说明没有环
        if (fast != low) return null;
        fast = head;
        //low待在原地  fast会原点   快慢指针每次都走一步直到找到相遇的位置 就是环的入口
        while (fast != low) {
            fast = fast.next;
            low = low.next;
        }
        return low;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章