题目描述
如果一个链表中包含环,如何找出环的入口?
解题思路:
- 先判断是否有环,如果没有话则没有入口:定义快慢指针slow, fast都指向头节点;遍历链表,slow一次走一步,fast一次走两步,如果slow和fast能相遇,则说明有环,记录相遇的节点为loopNode。
- 计算环的长度:从第1步里的loopNode开始循环,再次遍历到loopNode的时候,则将环遍历了一圈,可以算出环的长度n。
- 再次定义快慢指针slow, fast都指向头节点,fast先走n步骤,然后slow和fast同时每次走一步向后遍历,等到slow和fast相遇,则是环的入口。
代码
ListNode entryNodeOfLoop(ListNode head) {
if (head == null) {
return null;
}
// 先找出链表是否有环
ListNode slow = head;
ListNode fast = head;
ListNode loopNode = null;
while (true) {
if (fast.next == null || fast.next.next == null) {
break;
}
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
loopNode = fast;
break;
}
}
if (loopNode == null) {
// 说明没有环
return null;
}
// 找出环的长度
ListNode loopNodeTmp = loopNode.next;
int loopLength = 1;
while(loopNodeTmp != loopNode) {
loopNodeTmp = loopNodeTmp.next;
loopLength ++;
}
// 找出环的入口
slow = head;
fast = head;
for (int i = 0; i < loopLength; i++) {
fast = fast.next;
}
while (fast!= slow) {
fast = fast.next;
slow = slow.next;
}
return fast;
}
网友评论