要求
不能修改原链表且空间复杂度为O(1)
解法:双指针
快指针一次走两步,慢指针一次走一步。假设链表如果有环,环的长度为b,直线长度为a。从head走a步就到了环的第一个节点,从第一个节点走b步就又回到了入口。
在两指针相遇时,fast比slow多走了n圈。即slow走的距离 s = nb。 等式左右同时加a。此时slow就停在了环的入口。如何让slow恰好走a步?如果让另一个指针从head出发,走a步就也到了环的入口。即两指针相遇的地方就是环的入口。
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head, slow = head;
while (true) {
if (fast != null && fast.next != null && fast.next.next != null) {
fast = fast.next.next;
} else {
return null;
}
slow = slow.next;
if (slow == fast)
break;
}
//让fast从head开始一次走一步,此后二者相遇位置即环的入口
fast = head;
while (fast != slow) {
fast = fast.next;
slow = slow.next;
}
return fast;
}
}