1 题目链接
2 题目要求
对于一个给定的链表,返回环的入口节点,如果没有环,返回null
拓展:
你能给出不利用额外空间的解法么?
3 代码思路
人傻了,不利用额外空间意思是O(1)也不能用?这个是我钻牛角尖呢,还是题目描述不清楚呢?暂时理解为空间复杂度要求O(1)吧。
图中的思路理一下,清楚之后我们考虑,代码怎么写呢?倒走n,在单向链表上是不合理的,因此要转换为正向走过多少距离。通过慢指针我们能够清楚的看到,如果慢指针只走了m,那么不正是入口结点吗。因此我们只需要让慢指针从起点重新走,快指针从相遇结点开始走,两者同时走过距离m,即在入口处相遇。
4 代码实现
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode meetNode = getMeetNode(head);
if(meetNode == null)
return null;
// 快指针从相遇结点,慢指针从起点,每次走一步,相遇即为入口结点
ListNode slow = head;
ListNode fast = meetNode;
while(slow != fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
// 寻找相遇结点。快慢指针,快指针每次走两步,慢指针每次走一步。
public ListNode getMeetNode(ListNode head){
if(head == null)
return null;
ListNode slow = head;
ListNode fast = head;
// 无环则不在循环
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
// 快慢指针相遇
if(slow == fast)
return slow;
}
return null;
}
}