题目
在一个包含环的链表中,找出入口节点
步骤
- 1、用两个指针分别一快一慢移动,当两个节点都不为空且快的节点等于慢的节点时,那么该链表中有环
- 2、当找到相遇的节点时,那么该节点必定在环中,此时记录该节点、开始计数,当下一次节点回到该节点时,环循环结束,计数的count值即为环的节点数。
- 3、从头节点开始,让节点1先移动count个位子后,节点2=headNode与节点1开始一起移动,当节点1==节点2时,那么节点1的位置即为环的入口节点。
代码实现:
public class FindeLinkedListEntryNode {
public static class ListNode {
ListNode next = null;
int data;
public ListNode(int data) {
this.data = data;
}
}
public static void main(String args[]) {
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node5 = null;
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node3;
System.out.println(EntryNodeOfLoop(node1).data);
}
private static void printLinkedList(ListNode head) {
if (head != null) {
System.out.print(head.data + "->");
}
while (head.next != null) {
head = head.next;
System.out.print(head.data + "->");
}
System.out.println();
}
private static ListNode meetingNode(ListNode head) {
if (head == null) return null;
ListNode slowNode = head;
ListNode fastNode = slowNode.next;
if (fastNode == null) return null;
while (slowNode != null && fastNode != null) {
if (slowNode == fastNode) {
return fastNode;
}
slowNode = slowNode.next;
fastNode = fastNode.next;
if (fastNode != null) {
fastNode = fastNode.next;
}
}
return null;
}
private static ListNode EntryNodeOfLoop(ListNode pHead){
ListNode meetingNode = meetingNode(pHead);
if (meetingNode==null){
return null;
}
int nodeNum = 1;
ListNode pNode1= meetingNode;
while (pNode1.next!=null && pNode1.next!=meetingNode){
nodeNum++;
pNode1 = pNode1.next;
}
// 算出环节点个数 nodeNum
System.out.println("环节点个数:"+nodeNum);
pNode1 = pHead;
for (int i = 0; i < nodeNum; i++) {
pNode1 = pNode1.next;
}
ListNode pNode2 = pHead;
while (pNode1!=pNode2){
pNode1 = pNode1.next;
pNode2 = pNode2.next;
}
return pNode1;
}
}
输出结果:
环节点个数:2
3