这个题目可以分解为两个小问题:1.这个链表有没有环 2.如果有环,那么环的入口在哪里。
针对这两个问题,我先想到了用HashSet数据结构,这个数据结构的特点是不允许包含两个相同的元素,因此,我们只需要依次遍历链表元素,并且将元素插入到HashSet中,如果这个元素插入后HashSet的size不改变,则说明这个元素就是环的开始(因为它是第一个出现第二次的元素),因此写出代码如下:
/**
* 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||head.next==null)
{
return null;
}
Set<ListNode> a=new HashSet<ListNode>();
ListNode cur=head;
int size=0;
int i=1;
while(cur!=null)
{
a.add(cur);
size=a.size();
if(size!=i)
{
return cur;
}
i++;
cur=cur.next;
}
return null;
}
}
这个方法能通过,但是比较慢,只打败了19%,然后在代码随想录看到了更好的方法,运用双指针的方法,fast指针每次移动两个,slow指针每次移动1个,如果这两个指针再次相遇,说明有环。