思路一:快慢指针(原理:跑得快的,在一个圆内一定会再次超过跑得慢的)
/**
* 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 slow=head;
ListNode fast=head;
while(fast!=null && fast.next!=null)
{
fast=fast.next.next;
slow=slow.next;
if(fast==slow)
return true;
}
return false;
}
}
复杂度分析
时间 O(n) n 是链表中的节点数
空间 O(1) 只使用了两个指针的额外空间
思路二:哈希表(如果节点值重复呢?也是可以的,因为放进去的是对象 /链表节点)
import java.util.Set;
import java.util.HashSet;
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null || head.next==null)
return false;
Set<ListNode> set = new HashSet<ListNode>();
while (head != null) {
if (!set.add(head)) {
return true;
}
head = head.next;
}
return false;
}
}
复杂度分析
时间O(n) n链表节点数
空间O(n) 主要为哈希表的开销,最坏情况下我们需要将每个节点插入到哈希表中一次。
通俗解释:两个人同一起点绕操场跑,速度不一样,但是跑的时候速度不变,快的一定会超过慢的一圈(或者说两个人一定会再次相遇)