牛客百度算法题(简单)--判断链表是否有环(要求空间复杂度O(1))

题目

判断给定的链表中是否有环。如果有环则返回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;
    }
}

猜你喜欢

转载自blog.csdn.net/YSJ367635984/article/details/113247081
今日推荐