解决这个问题的第一步是如何确定一个链表中包含环。我们同样可以用两个指针解决这个问题。和前面的问题一样,定义两个指针,同时从链表的头结点出发,一个指针一次走一步,另一个指针一次走两步。如果快的指针追上了走的慢的指针,那么链表就包含环。
第二步是如何找到环的入口,我们还是可以用两个指针来解决这个问题。先定义两个指针P1和P2指向链表的头结点。如果链表中的环有n个节点,则指针P1先在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向换的入口节点,第一个指针已经围绕着换走了一圈,回到了入口。
剩下的问题是如何得到题目中环中节点的树木。我们在前面提到判断一个链表里是否有环时,用到了一块一慢的两个指针,如果两个指针相遇,则表明链表中存在环。两个指针相遇的节点一定是在环中,可以从这个节点出发,一边继续向前移动一边计数,当再次回到这个节点时,就可以的得到环中节点数了。
package question23_find_door;
/**
* @Classname Solution
* @Description TODO
* @Date 2020/3/26 17:25
* @Created by mmz
*/
public class Solution {
class ListNode{
int value;
ListNode next = null;
ListNode(int value) {
this.value = value;
}
}
public ListNode EntryNode(ListNode phead){
if(phead == null){
return null;
}
ListNode p1 = phead;
ListNode p2 = phead;
while(p1!=null &&p2!=null){
p1 = p1.next;
p2 = p2.next.next;
if(p1 == p2){
p2 = phead;
while(p1 != p2){
p1 = p1.next;
p2 = p2.next;
}
return p1;
}
return null;
}
}
}
二刷
package question23_链表中环的入口;
import java.util.List;
/**
* @Classname Main
* @Description TODO
* @Date 2020/4/11 20:58
* @Created by mmz
*/
public class Main {
static class ListNode{
int val;
ListNode next = null;
public ListNode(int val) {
this.val = val;
}
@Override
public String toString() {
return "ListNode{" +
"val=" + val;
}
}
static ListNode Core(ListNode head){
ListNode pre = head;
ListNode meet = Corefind(head);
if(head == null){
return null;
}
while(pre != meet){
pre = pre.next;
meet = meet.next;
}
return pre;
}
static ListNode Corefind(ListNode head){
ListNode first = head;
ListNode second = head;
while(first.next!= null && first.next.next!= null){
first = first.next.next;
second = second.next;
if(first == second){
return first;
}
}
return null;
}
public static void main(String[] args) {
ListNode one = new ListNode(1);
ListNode two = new ListNode(2);
ListNode three = new ListNode(3);
ListNode four = new ListNode(4);
ListNode five = new ListNode(5);
ListNode six = new ListNode(6);
one.next = two;
two.next= three;
three.next= four;
four.next = five;
five.next = six;
six.next =three;
ListNode node = Core(one);
System.out.println(node.toString());
}
}