141: 环形链表

156 阅读1分钟

题目描述

给你一个链表的头节点 head ,判断链表中是否有环。

分析

输入:链表头节点 head 输出:true/false 表示是否有环

解题方法

快慢指针

快指针可以追上慢指针则说明有环; 若到达链表尾部未相遇,则说明无环。

image.png

设置快慢指针 slow, fast, fast 每次走两步,slow 每次走一步, 那么这种情况下,如果链表有环,快指针一定会先进入链表环中,等到慢指针进入后,由于快指针速度是慢指针的两倍,那么一定会有块指针追上慢指针的情况,所以可以根据这点找到代码的输出

image.png

image.png

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} head
 * @return {boolean}
 */
var hasCycle = function(head) {
    // 变量:快慢指针,指向 head
    let slow = head
    let fast = head

    // 移动两个指针,速度差1倍
    while (fast && fast.next) {
        fast = fast.next.next
        slow = slow.next

        // 在环中相遇(若有环),返回 true
        if (fast === slow) return true
    }

    // 快指针到达链表尾部,两者未相遇,说明无环,返回 false
    return false
};

复杂度

时间:O(N), 若无环,每个节点最多被访问一遍; 若有环,链表长度为 N,因为在环里每走一步,快慢链表距离减小1,所以在 N 轮之内两指针一定相遇

空间:O(1), 两个指针存储对象的指针