[路飞]_环形链表 II

696 阅读1分钟

「这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战142. 环形链表 II

题目

能来搜索这个题解的,相信题目已经看过几遍了;直接上思路

解题思路

哈希表

最容易想到的思路,通过哈希表记录每一个节点,当节点在哈希表已经存在,并且再次枚举到节点时,节点有环,并且遇到的第一个在哈希表存在的节点就是环形链表的入环第一个节点

代码如下:

var detectCycle = function(head) {
    const set = new Set();
    while (head !== null) {
        if (set.has(head)) {
            return head;
        }
        set.add(head);
        head = head.next;
    }
    return null; 
};

双指针

用快慢指针,快指针与慢指针相遇,证明链表有环

链表有环;当快指针与慢指针相遇时,快指针重新指向链表头,再次相遇皆可得到入环第一节点

幻灯片1.gif

幻灯片2.gif

幻灯片3.gif

幻灯片4.gif

幻灯片5.gif

幻灯片6.gif

幻灯片7.gif

幻灯片8.gif

幻灯片9.gif

幻灯片10.gif

证明:

假设表头到入环节点长度为x;

入环节点到相遇节点长度为a;

相遇节点到入环节点长度为b;

当慢指针走到相遇节点时慢节点走的距离为x+a;快指针应该走了2(x+a)2*(x+a)

这是,快指针也到相遇节点,x+a+b+a = 2x + 2a;

得到 x = b

编辑代码如下:


var detectCycle = function(head) {
    let fast = head;
    let slow = head;
    while(fast && fast.next){
        fast = fast.next.next;
        slow = slow.next;
        if(slow === fast){
            fast = head;
            while(slow !== fast){
                fast = fast.next;
                slow = slow.next;
                
            }
            return slow
        }
    }
    return null;
    
};