题目:
判断给定的链表中是否有环。如果有环则返回true,否则返回false。
你能给出空间复杂度 O(1) 的解法么?
输入
无
输出
无
思路:
快慢指针判断法:设置两个指针,从同一个起点出发,一个速度为2个节点/次,一个速度为1个节点/次,
如果这个链表内不存在环。那么慢指针永远追不上快指针,直到快指针先遍历到NULL,退出循环,判断结束,输出false
如果这个链表内存在环,那么慢指针和快指针一定会一直绕环移动,并且某个时刻一定会重合,此时判断结束,输出true
为什么一定会相遇??,我们假设环的长度为L(L>=2)
快指针速度是2,慢指针速度为1,设运动时间为t,O是参照起点
慢指针点是M,快指针点是F,假设初始位移OF=x1,OM=x2,顺时针为正方向
则经过t 时间后,快指针 OF = (2 * t + x1) % L
经过t 时间后 ,慢指针 OM = ( t + x2 ) % L
那是否存在 t 使 (2 * t + x1) % L =( t + x2 ) % L ?
即判断 (2 * t + x1) 三( t + x2 ) mod L 是否存在实数解 t
这个式子等价于:(2 * t + x1 - (t + x2)) mod L = 0 (看不懂这个式子就再去看看模的定义)
化简:( t + x1 - x2 ) mod L = 0
肯定有解,傻瓜都知道有解!!!
所以快慢指针肯定会相遇,所以只需要判断快慢指针是否相遇就可以知道该链表有没有环了;
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode f = head;
ListNode m = head;
while(f!=null && f.next!=null){
f = f.next.next;
m = m.next;
if(f==m) return true;
}
return false;
}
}