本篇的两个问题由上一篇判断单链表是否有环(java)引申而出。
求环长
- 思路分析
快慢指针第一次相遇表示链表有环
快慢指针从第一次相遇开始到第二次相遇,期间慢指针走的步数即为环长 - 代码实现
public static int cycleLength(ListNode head) {
ListNode slow = head;
ListNode fast = head;
int cycleLength = 0;
// 标识快慢指针第一次相遇
boolean flag = false;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
flag = true;
break;
}
}
if (flag) {
while (true) {
slow = slow.next;
fast = fast.next.next;
cycleLength++;
// 第二次相遇
if (slow == fast) {
break;
}
}
}
return cycleLength;
}
求环入口
-
思路分析
-
代码实现
public static ListNode cycleEntrance(ListNode head) {
ListNode slow = head;
ListNode fast = head;
// 标识快慢指针第一次相遇
boolean flag = false;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
flag = true;
break;
}
}
if (flag) {
// p1从头结点开始, 步长为1
ListNode p1 = head;
// p2从第一次相遇点开始,步长为1
ListNode p2 = slow;
while (p1 != p2) {
p1 = p1.next;
p2 = p2.next;
}
// 退出循环表示p1,p2相遇在环入口
return p1;
}
return null;
}