思路:双指针+哈希表
双指针这里的类型是快慢指针,前面也说过,常用于查找链表的中点或者判断有无环的应用。
首先用快慢指针一个走一个结点,一个走两个结点,判断这个链表有无环?如果没有,直接返回null;如果有,那么进行下面的操作:
我们设置哈希表用来存放结点和结点的个数键值对。然后用一个指针遍历链表。当出现一个结点出现两次的时候,那么此结点就是环的入口结点。
注意:只要不把哈希表的两个参数设为<Integer,Integer>,而是把哈希表两个参数设为<ListNode,Integer>就行,因为如果你那每一个结点的元素值作为Key,那么这个时候当你判断环的入口时就会出现明明不是出口,但是落在一个值相同的节点上。
其实设成<Integer,Integer>也是可以的,但是我们需要首先判断出来链表的长度,在进行判断环的入口的时候需要额外判断是否遍历了比链表长度还长的路程,这样才能判断出来。但问题是,这里并不能用方法来判断有环链表的长度,只能判断无环链表的长度,所以这种想法也只是一种参考。
/**
* 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;
Map<ListNode,Integer>map=new HashMap<ListNode,Integer>();
ListNode slow=new ListNode(-1);
slow.next=head;
ListNode fast=head;
boolean flag=false;
while(fast!=null&&fast.next!=null){
slow=slow.next;
fast=fast.next.next;
if(fast==slow){
flag=true;
break;
}
}
if(flag==false){
return null;
}
else{
ListNode tmp=head;
while(tmp!=null){
map.put(tmp,map.getOrDefault(tmp,0)+1);
if(map.get(tmp)>=2){
return tmp;
}
tmp=tmp.next;
}
return null;
}
}
}