如果一个链表中包含有环,如何找出这个环的入口?
例如:链表中环的入口为3.
思路:
1.我们得确定链表中有环。 2 去找环的入口
- 使用两个指针,一快一慢,快指针每次走2步,慢指针每次走1步,当快指针都指向null了还没有追上慢指针,这就说明链表无环。
- 确定链表中环的节点个数,当第一步两个节点相遇后,我们这时候开始找环中节点个数。从相遇节点开始,往后面迭代做计数,当再次回到这个节点的时候,走的步数就是环中节点的个数
- 知道环中节点的个数后比如为k个,我们仍然使用快慢两个指针,先让快指针走k步,然后快慢指针一起走,当两节点相遇的时候,该节点就是环的入口。
// 查找链表环的入口
public void findCycleNodeEntry(Node head){
Node firstMetting = hasCycle(head);
if (firstMetting == null)return; //没有环,
//找环中节点的个数
Node p = firstMetting;
int count = 0;
p = p.next;
count++;
while (p != firstMetting ){
p = p.next;
count++;
}
//从表头开始,快指针先走count步
Node fast = head;
Node slow = head;
for (int i = 0; i < count; i++){
fast = fast.next;
}
while (fast != slow){
fast = fast.next;
slow = slow.next;
}
System.out.println(fast.data);
}
//判断是否有环,返回相遇节点
public Node hasCycle(Node head){
if (head == null || head.next == null)return null;
Node fastN = head;
Node slowN = head;
while (fastN != null && slowN != null){
if (fastN.next == null){
return null;
}
fastN = fastN.next.next;
slowN = slowN.next;
if (fastN == slowN){
System.out.println("has cycle");
return fastN;
}
}
return null;
}