力扣 141题 环形链表

Question 141-linked list cycle

解题思路

这里大致记录两种解题思路:哈希表 和 双指针

  • 哈希表
    首先我们准备一个HashSet,然后开始遍历这个链表。在遍历的过程中,将已经遍历到了的节点放入这个 hashset 中。如此可知:如果你搜索到一个已经存在于该 hashset 中的节点,那么这个链表就是环形链表。

  • 双指针
    从环形链表的定义可知:如果我们将链表的每个节点看作是跑道的一部分,而一整个链表就是一个跑道,那么我们一共可能会有两种跑道:
    环形链表
    直链表
    想象一下,如果有两个人,在跑道上跑,一个跑的快,另一个跑的慢,那么他们一个会遇到两种情况:

  1. 跑道是环形的,跑的快的人会遇到跑的慢的人
  2. 跑道是直的,跑得快的人永远都不会遇到跑得慢的人
    如果你再把这两个人想象称两个指针,那么“在跑道上跑”就等同于“遍历链表”了。如果我们在遍历的每一次都检查一下两个指针指向的节点,那么我们一共可能遇到两种情况:
  3. 链表是环形的,两个指针指向的节点可能会相同(跑得快的指针与跑得慢的指针相遇了)
  4. 链表是直的,跑得快的指针率先冲到了链表的尽头(null)

代码

  • 哈希表
public class Solution {
    public boolean hasCycle(ListNode head) {
        
        Set<ListNode> singly = new HashSet();
        
        while (head != null) {

            if (!singly.add(head)) {

                return true;
            }
            head = head.next;
        }

        return false;
    }
}
  • 双指针
public class Solution {
    public boolean hasCycle(ListNode head) {

        if (null == head) return false;

        ListNode fast = head.next;
        ListNode slow = head;

        while (fast != slow) {

            if (fast == null || fast.next == null) return false;

            fast = fast.next.next;
            slow = slow.next;
        }

        return true;
    }
}
posted @ 2021-07-09 16:29  寻落英以得度  阅读(84)  评论(0)    收藏  举报