----------------------------------------------本题链接----------------------------------------------
题目描述
对于一个给定的链表,返回环的入口节点,如果没有环,返回null
拓展:
你能给出不利用额外空间的解法么?
示例
输入
链表:{1,2,3,4,5,2}
返回值
节点:2
思路
还是使用快慢指针(好像已经遇见很多次了),抓住快指针走的距离是慢指针的两倍这个特点
如果有环,则两个指针必然会在环上某点相遇;如果无环,则两指针必不会相遇,且快指针会指向null
接下来看图解释会更方便(借用某大佬的图)
快慢指针在Z点相遇,此时快指针走过的路径是 a+b+c+b,慢指针走过的路径是 a+b。由于快指针走的距离是慢指针的两倍,则有a+b+c+b=2(a+b),求出来a=c。
根据这个结果,我们再让一个新节点从头节点出发,慢节点从Z点出发,当这两个节点相遇,就到了环的入口节点
算法过程
- 采用快慢指针,求解两指针相遇节点
- 初始化一个新指针指向头节点
- 新指针和慢指针同时走,当两者相遇输出相遇节点
解答
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head == null || head.next == null) return null;
ListNode slow = head, fast = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast){
ListNode begin = head;
while(begin != fast){
begin = begin.next;
fast = fast.next;
}
return begin;
}
}
return null;
}
}