链表中环的入口节点 | 刷题打卡

82 阅读2分钟

题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

思路分析

声明两个指针 P1 P2

  • 1.判断链表是否有环: P1 P2 从头部出发,P1走两步,P2走一步,如果可以相遇,则环存在

  • 2.从环内某个节点开始计数,再回到此节点时得到链表环的长度 length

  • 3.P1、P2 回到head节点,让 P1 先走 length 步 ,当P2和P1相遇时即为链表环的起点

    foo

AC代码

class nodeList {
    constructor(val) {
        this.val = val;
        this.next = null;
    }
}
/* 
1.判断链表是否有环: P1 P2 从头部出发,P1走两步,P2走一步,如果可以相遇,则环存在

2.从环内某个节点开始计数,再回到此节点时得到链表环的长度 length

3.P1、P2 回到head节点,让 P1 先走 length 步 ,当P2和P1相遇时即为链表环的起点
*/
function EntryNodeOfLoop(head) {
    if (!head || !head.next) {
        return null
    }
    let p1 = head;
    let p2 = head.next;
    //1.判断是否有环
    while (p1 != p2) {
        if (p2 === null || p2.next === null) {
            return null;
        }
        p1 = p1.next;
        p2 = p2.next.next;
        
    }
    //2.获取环的长度
    let temp = p1;
    let length = 1 ;
    p1 = p1.next;
    while(temp != p1) {
        p1 = p1.next;
        length++
    }
    //3.找公共节点
    p1 = p2 = head;
    while (length > 0) {
        p2 = p2.next;
        length--;
    }
    while(p1 != p2) {
        p1 = p1.next;
        p2 = p2.next;
    }
    return p1;
}

let node1 = new nodeList(1);
let node2 = new nodeList(2);
let node3 = new nodeList(3);
let node4 = new nodeList(4);
let node5 = new nodeList(5);
let node6 = new nodeList(6);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node6;
node6.next = node3;
console.log(EntryNodeOfLoop(node1));

总结

这道题的重点就是如何判断一个链表是否有环,做法就是用两个指针,第一个指针p1指向head,第二个指针p2指向head.next。然后开始循环每次第一个指针向前走一步,第二个指针向前走两步。如果p1 === p2就说明这个链表中存在环,跳出循环。

跳出循环后寻要找到这个环的长度,就是循环,当指针cur再次等于p1时,就得到了环的长度

第三步就是寻找入口节点,让p1,p2重新都会到head,然后p2先走length步,然后p1,p2一起往前走,此时p1 ===p2的那个节点就是入口节点。

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 [活动详情](