package com.niuke;
import java.util.HashSet;
/**
* Created by admin on 2018/3/11.
* /*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class EntryNodeOfLoop {
public ListNode entryNodeOfLoop(ListNode pHead) {
/**
第一步,找环中相汇点。分别用fast,slow指向链表头部,slow每次走一步,
fast每次走二步,直到fast==slow找到在环中的相汇点。
第二步,找环的入口。接上步,当fast==slow时,fast所经过节点数为2x,slow所经过节点数为x,
设环中有n个节点,fast比slow多走一圈有2x=n+x; n=x;可以看出slow实际走了一个环的步数,
再让fast指向链表头部,slow位置不变,slow,fast每次走一步直到slow==fast; 此时slow指向环的入口。
*/
if(pHead==null||pHead.next==null) {
return null;
}
ListNode fast=pHead;
ListNode slow=pHead;
while (fast!=null&&fast.next!=null) {
fast=fast.next.next;//fast每次走两步
slow=slow.next;//slow每次走一步
if(fast==slow) {//他们在环中相遇 fast走的步数是slow的二倍 一圈的步数就是slow现在走的步数
fast=pHead;//fast从头以slow的一次一步再走
while (fast!=slow) {
fast=fast.next;
slow=slow.next;
}
return slow;//相遇时就是入口处
}
}
return null;
}
//2 HashSet求解
public ListNode EntryNodeOfLoop2(ListNode pHead)
{
if(pHead==null||pHead.next==null) {
return null;
}
HashSet<ListNode> set=new HashSet<>();
while (pHead!=null) {
if(!set.add(pHead)) {
return pHead;
}
pHead=pHead.next;
}
return null;
}
//3 断链法 或者叫标记法
public ListNode EntryNodeOfLoop3(ListNode pHead)
{
if(pHead==null||pHead.next==null) {
return null;
}
ListNode fast=pHead.next;
ListNode slow=pHead;
while (fast!=null) {
slow.next=null;//每次访问过将其断开
slow=fast;
fast=fast.next;
}
return slow;
}
}
链表中环的入口结点
最新推荐文章于 2025-05-15 09:37:00 发布