JS实现两个链表的第一个公共结点

分析:
首先要理解什么是公共节点,并不是两个节点的值相同就是公共节点。
而是在第一链表和第二链表中都存在一个节点,该节点往后的子链表在两个链表中是相同的。

方法一
最直观就是暴力法,在第一链表上顺序遍历每个节点,每遍历到一个节点,就在第二个链表上顺序遍历每个节点。如果在第二个链表上有一个节点和第一个链表上的节点一样,则说明两个链表在这个节点上重合,但是这种方法的复杂度为O(m * nm∗n)(第一个链表长度为m,第二个链表的长度为n)

方法二
如果两个链表存在公共节点,那么公共节点出现在两个链表的尾部。如果我们从两个链表的尾部开始往前比较,那么最后一个相同的节点就是我们要找的节点。但是这两个链表是单向的,要实现尾节点最先比较,我们可以借助两个辅助栈。分别将两个链表的节点放入两个栈中,这样栈顶就是两个链表的尾节点,比较两个栈顶节点是否相同,如果相同,将栈顶弹出比较下一个栈顶,直到找到最后一个相同的栈顶。时间复杂度O(m + n)。

// 思路1
function FindFirstCommonNode(pHead1, pHead2)
{
    // write code here
    if (!pHead1 || !pHead2) {
        return null
    }
    let arr1 = []
    let arr2 = []
    while (pHead1) {
        arr1.push(pHead1)
        pHead1 = pHead1.next
    }
    while (pHead2) {
        arr2.push(pHead2)
        pHead2 = pHead2.next
    }
    let i = arr1.length - 1
    let j = arr2.length - 1
    let same = null
    while (i >= 0 && j >=0) {
        if (arr1[i] === arr2[j]) {
            same = arr1[i]
        }
        i--
        j--
    }
    return same
}

方法三
先获得两个链表的长度,然后在较长的链表上先走若干步(两链表长度之差),接着同时在两个链表上遍历,找到的第一个相同的节点就是他们的第一个公共节点。时间复杂度O(m + n)。

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function FindFirstCommonNode(pHead1, pHead2) {
    // write code here
    if (!pHead1 || !pHead2) {
        return null
    }
    const len1 = getLinkLength(pHead1),
        len2 = getLinkLength(pHead2);
    let pLong = pHead1,
        pShort = pHead2,
        lenGap = len1 - len2;
    if (len1 < len2) {
        pLong = pHead2;
        pShort = pHead1;
        lenGap = len2 - len1;
    }
    while (lenGap--) {
        pLong = pLong.next;
    }
    while (pLong !== null) {
        // pLong,pShort一起跑
        if (pLong.val === pShort.val) {
            return pLong;
        }
        pLong = pLong.next;
        pShort = pShort.next;
    }
    return null;

}
function getLinkLength(pHead) {
    let length = 0;
    while (pHead !== null) {
        pHead = pHead.next;
        length++;
    }
    return length;
}

方法四
用两个指针扫描”两个链表“,最终两个指针到达 null 或者到达公共结点。

参考:两个链表中的第一个公共节点——js
剑指OFFER----52、两个链表的第一个公共节点(js实现)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值