package com.wsy.sword;
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public class EntryNodeOfLoop
{
/*
* 链表中环的入口结点
* 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
*
* 思路:主要利用双指针思路
* 1.先用双指针判断是否有环,first走一步,second走两步找到相遇点,无环则直接返回。
* 2.根据第一步得到的环中的点获取环的长度
* 3.利用前后指针,先让second走len步,判断first == second 或者 first.next == second.next则返回,否则返回null
*/
public ListNode entryNodeOfLoop(ListNode pHead){
ListNode node = null;
//先判断是否有环
if((node = hasLoop(pHead)) == null){
return null;
}
//获取链表长度
int len = 1;
ListNode nodeLoop = node.next;
while(node != nodeLoop){
len++;
nodeLoop = nodeLoop.next;
}
//获取链表入口
ListNode first = pHead;
ListNode second = pHead;
for (int i = 0; i < len; i++){
second = second.next;
}
/*
* 有两种环(走到这肯定是有环):
* 1、起点就在环里,进到循环第一次判断就会跳出
* 2、起点不在环里,进到循环需要遍历后才能跳出
*/
while(first != null && second != null){
if(first == second){
return first;
}
first = first.next;
second = second.next;
}
return null;
}
private ListNode hasLoop(ListNode pHead){
ListNode first = pHead;
ListNode second = pHead;
while(second != null && second.next != null){
first = first.next;
second = second.next.next;
if(first == second){
return first;
}
}
return null;
}
}
链表中环的入口结点
最新推荐文章于 2024-02-16 09:40:30 发布