Loading

剑指offer[36]——两个链表的第一个公共结点

题目描述

输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)

方法一

如图是两个具有公共节点的链表,我们可以发现一个规律,从公共节点到最后的节点两个链表都是重复的,所以我们只需要找出第一个重复的节点就可以了。注意,这里的重复并不是指val值重复,而是指其val值与next指向全部相等。

这里我采取的做法是将两个链表初始化为同样的长度,然后才遍历寻找公共节点,代码如下:

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function FindFirstCommonNode(pHead1, pHead2)
{
    let len1 = 0;
    let len2 = 0;
    let _pHead1 = pHead1;
    let _pHead2 = pHead2;
    while(_pHead1 || _pHead2){
        if(_pHead1){len1++;_pHead1=_pHead1.next;}
        if(_pHead2){len2++;_pHead2=_pHead2.next;}
    }
    let max = len1;
    let min = len2;
    if(len1<len2){
        [pHead1, pHead2] = [pHead2, pHead1];
        max = len2;
        min = len1;
    }
    for(let i=0; i<max-min; i++){
        pHead1 = pHead1.next;
    }
    while(pHead1){
        if(pHead1==pHead2){return pHead1;}
        pHead1 = pHead1.next;
        pHead2 = pHead2.next;
    }
    return null;
}

方法二

此方法借鉴牛客网大佬的做法,链接

看下面的链表例子:
0-1-2-3-4-5-null
a-b-4-5-null
代码的ifelse语句,对于某个指针p1来说,其实就是让它跑了连接好的的链表,长度就变成一样了。
如果有公共结点,那么指针一起走到末尾的部分,也就一定会重叠。看看下面指针的路径吧。
p1: 0-1-2-3-4-5-null(此时遇到ifelse)-a-b-4-5-null
p2: a-b-4-5-null(此时遇到ifelse)0-1-2-3-4-5-null
因此,两个指针所要遍历的链表就长度一样了!
如果两个链表存在公共结点,那么p1就是该结点,如果不存在那么p1将会是null。

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function FindFirstCommonNode(pHead1, pHead2)
{
    if(!pHead1 || !pHead2){return null;}
    let _pHead1 = pHead1;
    let _pHead2 = pHead2;
    while(_pHead1!=_pHead2){
        _pHead1 = _pHead1.next;
        _pHead2 = _pHead2.next;
        if(_pHead1!=_pHead2){
            if(!_pHead1){_pHead1=pHead2;}
            if(!_pHead2){_pHead2=pHead1;}
        }
    }
    return _pHead1;
}
posted @ 2020-03-27 11:30  Jacob是我了  阅读(268)  评论(0编辑  收藏  举报