LeetCode 141. Linked List Cycle

Given a linked list, determine if it has a cycle in it.

Follow up:
Can you solve it without using extra space?

题意:给定一个链表,判断链表中是否存在环路。

注:不能使用额外的空间

思路:百度的解决方法。设置一个快指针,一个慢指针。存在环路的链表相当于钟表,快指针和慢指针相当于分针和时针,在钟表中,分针比时针快,但两者总会有重叠的时候。在链表中道理相同,如果链表存在环路,则两个快慢指针总会重叠(即指向同一个结点)。

参考:https://www.cnblogs.com/grandyang/p/4137187.html

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

LeetCode提供的解决方法:

1. 原理相同,只是与上述方法中的循环结束条件不同

public boolean hasCycleTwo(ListNode head) {
        if (head == null || head.next == null)
            return false;
        ListNode slow = head;
        ListNode fast = head.next;
        // 如果slow和fast第一次都指向head,则有slow==fast,因此在初次定义的时候fast要指向head.next,因此要先判断head.next不为空
        while (slow != fast) {
            if (fast == null || fast.next == null)
                return false;
            slow = slow.next;
            fast = fast.next.next;
        }
        return true;
    }

2. 利用集合。为了检测链表中是否存在环路,从head开始逐个加入集合,检查该结点是否在之前被访问过。但该方法需占用额外空间
注:也可以使用线性表,但在测试一个元素是否在集合或线性表方面,集合比线性表更加高效。

public boolean hasCycle(ListNode head) {
        Set<ListNode> set = new HashSet<>();
        ListNode cur = head;
        while (cur != null) {
            if (!set.contains(cur))
                set.add(cur);
            else
                return true;
            cur = cur.next;
        }
        return false;
    }
原文地址:https://www.cnblogs.com/zeroingToOne/p/8059599.html