#剑指offer36两个链表的第一个公共结点
两个链表的第一个公共结点
https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tpId=13&&tqId=11189&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
剑指offer36两个链表的第一个公共结点
剑指offer36
其他博客解读参考
1、直接双重循环比较
个人答案
//直接两重循环比较
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode* temp=pHead2;
while(pHead1)
{
pHead2=temp;
while(pHead2)
{
if(pHead1==pHead2)
return pHead1;
pHead2=pHead2->next;
}
pHead1=pHead1->next;
}
return nullptr;
}2、差值法(较长优先走):两个链表在公共节点之前长度不一定一致,所以不能同时遍历比较。可以让长的先走n-m步,然后再同时走,进行比较
个人答案
//双指针法1:两个链表在公共节点之前长度不一定一致,所以不能同时遍历比较。
// 可以让长的先走n-m步,然后再同时走,进行比较
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
int n=0;
int m=0;
ListNode* head1=pHead1;
ListNode* head2=pHead2;
while(pHead1)
{
++n;
pHead1=pHead1->next;
}
while(pHead2)
{
++m;
pHead2=pHead2->next;
}
if(n>m)
{
int x=n-m;
while(x--)
{
head1=head1->next;
}
}
else if(m>n)
{
int x=m-n;
while(x--)
{
head2=head2->next;
}
}
while(head1&&head2)
{
if(head1==head2)
return head1;
head1=head1->next;
head2=head2->next;
}
return nullptr;
}2、双指针法
个人答案
两个链表公共的前缀部分可能不一致,可以使用差值法,长的提前走完差值长度,但需要多次遍历.
也可以将两个链表接在一起长度均为m+n,即相当于两个链表分别加上对方链表作为自己的前缀,从而使得,两链表公共部分之前的前缀长度一致,可以同时走到公共部分。
注意:
1、若两链表长度一致,在附加前缀部分就可以找出公共点(无论有无公共点)
2、a+b之后,两个链表长度一致,所以有公共节点,返回公共节点,遍历次数<=m+n;无公共节点,尾部nullptr也可以看作虚拟的公共节点,返回虚拟公共节点nullptr,遍历m+n+1次
class Solution {
public:
//双指针法:两个链表公共的前缀部分可能不一致,可以使用差值法,长的提前走完差值长度,
// 但需要多次遍历.
// 也可以将两个链表接在一起长度均为m+n,即相当于两个链表分别加上对方链表作为自己的前缀
// 从而使得,两链表公共部分之前的前缀长度一致,可以同时走到公共部分。
//注意:1、若两链表长度一致,在附加前缀部分就可以找出公共点(无论有无公共点)
// 2、a+b之后,两个链表长度一致,所以有公共节点,返回公共节点,遍历次数<=m+n;
// 无公共节点,尾部nullptr也可以看作虚拟的公共节点,返回虚拟公共节点nullptr,遍历m+n+1次
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode* head1=pHead1;
ListNode* head2=pHead2;
while(head1!=head2)
{
head1=head1?head1->next:pHead2;//head1==null时,换上另一个链表
head2=head2?head2->next:pHead1;
}
return head1;
}
};
文远知行公司福利 510人发布
查看10道真题和解析