142. 环形链表 II

106 阅读1分钟

Problem: 142. 环形链表 II

image.png

方法一:快慢指针

思路

使用双指针技巧中的快慢指针方法,构建两次相遇。

  • 第一次相遇:具体来说,快指针每次走两步,慢指针走一步,最后两个指针会有第一次相遇,这时候快指针走的步数是慢指针的两倍。

image.png

  • 第二次相遇:重新定义一个指向头的指针,再和慢指针一起走,如果该指针走到和慢指针相等的位置,即环入口的位置。

image.png

代码


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

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var detectCycle = function(head) {
    let slow = head, fast = head;
    while (true) {
        if (!fast || !fast.next) return null;
        slow = slow.next;
        fast = fast.next.next;
        if (fast === slow) break;
    }

    fast = head;
    while(fast !== slow) {
        fast = fast.next;
        slow = slow.next;
    }

    return fast;
};

复杂度分析

时间复杂度空间复杂度
O(n)O(1)

方法二:哈希表

思路

使用哈希表,遍历指针的时候,先判断这个节点是否在表中,如果在,则是环的入口,不在则放入哈希表中。

代码


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

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var detectCycle = function(head) {
    const visited = new WeakSet();
    while(head) {
        if (visited.has(head)) {
            return head;
        }
        visited.add(head)
        head = head.next;
    }
    return null;
};

复杂度分析

时间复杂度空间复杂度
O(n)O(n)

同类题

141. 环形链表

参考资料

环形链表 II(双指针法,清晰图解)

环形链表 II