快指针走两格,慢指针走1格,若有环,则一定会相遇。
简单理解:
一定是快指针先进入环中,若慢指针也进入环中,则两者速度差1。
相当于慢指针不动(相对静止),而快指针以速度为1,追赶慢指针,(是环,一定会遇到)
若没有环,则快指针将会先到达尾部。
时间复杂度O(n),空间复杂度O(1)
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
//当链表没有元素或者只有一个元素(且没环)
if(head==null||head.next==null)
return false;
ListNode fast=head;
ListNode slow=head;
/*
Q1:为什么对slow判断是否为空呢?
答:因为若没环,fast先到底,while能判断结束
若有环,则永远不会为空
Q2:fast.next!=null 为啥加这个
答:因为在循环内有fast=fast.next.next;
若fast.next==null,则执行此句会报错
*/
while(fast!=null&&fast.next!=null)
{
slow=slow.next;
fast=fast.next.next;
if(slow==fast)
return true;
}
return false;
}
}
这个只是解决环路问题一种空间复杂度比较好的方法,还有简单可以想到的方法--集合思想,将遍历过的数字放入set集合中,在放时判断集合是否含有,若含有,则说明有环;若遍历结束,则说明没有环。
快慢指针例子参考:141环形链表https://leetcode-cn.com/problems/linked-list-cycle/
集合例子参考:142环形链表iihttps://leetcode-cn.com/problems/linked-list-cycle-ii/submissions/
这个例子也可以用快慢指针,但是比较复杂。