Leetcode原题:142 力扣https://leetcode.cn/problems/linked-list-cycle-ii/
题目描述:
题目分析:
有两种方案:(1)使用容器:把所有的节点都添加到HashSet里,直到某个节点要添加但是已经存在于HashSet中,这个节点就是第一个入环节点,这个方法的空间复杂度是O(N),不符合题目要求
(2)使用快慢指针,定义两个指针,都从头开始走,快指针每次走两步,慢指针每次走一步,两者相遇的时候,快指针回到开头,改成每次走一步,快慢指针再次相遇的点就是第一个入环的节点,各种典型场景分析
这个是靠经验,无需证明其正确性,leetCode超过100%的人
直接上代码
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head == null || head.next == null || head.next.next == null) {
return null;
}
//使用快慢指针,快指针一次跳两个节点,慢指针一次跳一个节点
ListNode fast = head.next.next;
ListNode slow = head.next;
//如果slow和fast没有相遇
while(slow != fast) {
//如果fast已经为空,或者它的next为空,不管哪个为空,都说明无环
if(fast == null || fast.next == null) {
//无环返回null
return null;
}
//快指针一次跳两个节点
fast = fast.next.next;
//慢指针一次跳一个节点
slow = slow.next;
}
//走到这里(跳出循环且没有返回)说明确实有环
//fast退回head位置,每次走一步
fast = head;
//跳出循环一定是第一次相遇的节点
while(slow != fast) {
slow = slow.next;
fast = fast.next;
}
//返回fast或者slow都行
return slow;
}
}
题目比较简单,我也写了大量的注释,不明白的可以私信我