【问题标题】:How to check if a linked list has a cycle in Java?如何检查链表在Java中是否有循环?
【发布时间】:2026-01-25 22:40:01
【问题描述】:

我有以下实现来检查链表是否有循环。如果是,则返回 true,否则返回 false。

看起来代码是正确的,但即使它确实有一个循环,它也会返回 false。我错过了什么?谢谢

import java.util.*;

class ListNode {
     int val;
     ListNode next;

     ListNode(int x) {
        val = x;
        next = null;
     }
 }

class LinkedListCycle {
    boolean hasCycle(ListNode head) {
        if(head == null) {
            return false;
        }

        ListNode walker = head;
        ListNode runner = head;

        while(runner.next!=null && runner.next.next!=null) {
            walker = walker.next;
            runner = runner.next.next;
            if(walker==runner) return true;
        }

        return false;
    }

    public static void main(String args[]) {
        LinkedListCycle llc = new LinkedListCycle();

        ListNode ln = new ListNode(1);
        ln.next = new ListNode(2);
        ln.next.next = new ListNode(3);
        ln.next.next.next = new ListNode(4);
        ln.next.next.next.next = new ListNode(2);
        ln.next.next.next.next.next = new ListNode(1);

        System.out.println(llc.hasCycle(ln));
    }
 }

【问题讨论】:

  • 如果存在循环并且返回false,您最好发布案例。

标签: java algorithm linked-list cycle


【解决方案1】:

算法确实是正确的: walker 前进一步,runner 前进两步, 如果列表有循环,最终会相遇, 否则到达列表的末尾。

这个循环检测实现不是根据节点值检测循环,而是根据节点检测循环。 就nodes而言,这里没有循环:

ListNode ln = new ListNode(1);
ln.next = new ListNode(2);
ln.next.next = new ListNode(3);
ln.next.next.next = new ListNode(4);
ln.next.next.next.next = new ListNode(2);
ln.next.next.next.next.next = new ListNode(1);

如果这样写的话,会有:

ListNode ln = new ListNode(1);
ln.next = new ListNode(2);
ln.next.next = new ListNode(3);
ln.next.next.next = new ListNode(4);
ln.next.next.next.next = ln.next;

【讨论】:

  • 非常感谢您的澄清。那么节点值实际上是必要的吗?步行者最终会如何遇到跑步者?
  • 节点值是数据。数据结构的重点是包含一些数据,不是吗。在这个练习中,它们可能看起来毫无意义,这就是练习的方式。步行者和跑步者相遇,就像你和一个跑得更快的人一起绕圈跑,他最终会超越你,一次又一次,一次又一次。