题目描述
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
方法一
如图是两个具有公共节点的链表,我们可以发现一个规律,从公共节点到最后的节点两个链表都是重复的,所以我们只需要找出第一个重复的节点就可以了。注意,这里的重复并不是指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;
}