关于链表存在环的几种问题 快慢指针法:
- 1、两个指针初次相遇证明有环
- 2、如果要求环长,初次相遇后,继续正常走下去,第二次相遇时慢指针刚好走一圈,就是环长度。
- 3、求环入口节点
以下对于第3个问题的解释:
如果D够长,那么D=S2+好几圈,但最终还是会在入口节点相遇,解释如下
方法1:快慢指针法
/**
* 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) {
ListNode fast = head;
ListNode slow = head;
while (fast!=null && fast.next!=null) {
fast = fast.next.next;
slow = slow.next;
//如果首次相遇
if(slow == fast) {
//fast回到初始
fast = head;
//一次变为走一步,再次相遇就是入口节点
while (fast!=slow) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
return null;
}
}
方法2:哈希set法
- 遍历单链表的每个结点
- 如果结点没有出现在set中,则存入set中
- 否则,出现在set中,则当前结点就是环的入口结点
- 整个单链表遍历完,若没出现在set中,则不存在环
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead) {
HashSet <ListNode>set=new HashSet<>();
while(pHead!=null){
if(!set.contains(pHead)){
set.add(pHead);
pHead = pHead.next;
}else{
return pHead;
}
}
return null;
}
}