判断单链表是否有环(java)

图示

  • 一般而言的单链表的尾部结点的next域指向null,是没有环的;
    在这里插入图片描述

  • 当单链表的尾部结点的next域指向其前面任一结点时,则证明链表有环。
    判断单链表是否有环(java)_第1张图片

思路分析

  • 定义两个指针,快指针和慢指针,快指针步长为2,慢指针步长为1。
  • 如果链表有环,则两个指针一定可以在环内相遇(为什么?可以很明确的一点是,如果链表没有环,两个指针永远不会相遇。接下来只需要证明在有环的情况下,两个指针一定会相遇,证明见图解2
  • 图解
  1. 特例
    判断单链表是否有环(java)_第2张图片

  2. 两指针一定会相遇的证明
    判断单链表是否有环(java)_第3张图片
    以fast为起点,把环想象成一个无限延伸的直线,问题转换为直线距离的追及问题,直到fast追上slow为止。
    在这里插入图片描述

    ① 假设fast和slow相距x,fast速度为2,slow速度为1,时间t后,两者相遇
    则一定有t+x = 2t => x = t,换言之就是,两者相距x,再移动x次就追上了
    判断单链表是否有环(java)_第4张图片
    ② 再回到环,一定有 x属于[0,L),所以经过有限次移动一定可以相遇

代码实现

public static boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                return true;
            }
        }
        return false;
    }

你可能感兴趣的:(数据结构和算法,1024程序员节,指针,链表,单链表,java)