题目:
输入两个链表,找出它们的第一个公共结点。
解法:
提供两种解法,都为o(m+n)的时间复杂度。
前提:因为为普通链表,若两个链表有交点,从该交点开始,后面的节点都是公共的。
即有交点的话,两条链表形成Y形, 而不是X形。
(一)
假设链表1为a-b-c-d-e-NULL, 链表2为f-g-e-NULL.分别遍历两个新的组合遍历
(链表1+链表2 : a-b - c - d - e - NULL- f - g - e - NULL)
(链表2+链表1 : f- g - e -NULL-a- b - c - d - e - NULL)
我们可以发现,第一个相同位置的交点为e,即为 第一个公共交点。
代码如下:
但是注意在(node1==NULL)?这个判断中,不能改为(node1->next==NULL)?会导致在无交点情况死循环,无法结束。
假设:链表1:abcde 链表2:fg 即该写法遍历的方式为
(abcdefg fg fg....)
(fgabcde abcde abcde....)
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1==NULL || pHead2 ==NULL)
return NULL;
ListNode* node1 = pHead1;
ListNode* node2 = pHead2;
while(node1!=node2)
{ //不能改为(node1->next==NULL)?,否则在没交点情况下会陷入死循环
node1 = (node1==NULL)? pHead2:node1->next; //链表1 结束后 转至链表2
node2 = (node2==NULL)? pHead1:node2->next; //链表2 结束后 转至链表1
}
return node1;
}
(二)
先各自遍历两个链表得到两个链表长度len1和len2. 让长的链表从头开始先前移abs(len2-len1)
然后一起移动两个节点,比较是否相同,若有交点,则返回第一个交点,若无则最后在NULL处汇集。
代码如下:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1==NULL||pHead2==NULL)
return NULL;
int len1=1;
int len2=1;
ListNode* node1 =pHead1;
ListNode* node2 = pHead2;
while(node1->next!=NULL)//获取长度
{
len1++;
node1=node1->next;
}
while(node2->next!=NULL)
{
len2++;
node2=node2->next;
}
node1 = pHead1;
node2 = pHead2;
if(len1>len2)//链表1长
{
for(int i =0;i<len1-len2;i++)
node1=node1->next;
while(node1!=node2)
{
node1=node1->next;
node2=node2->next;
}
}
else//链表2长
{
for(int i =0;i<len2-len1;i++)
node2=node2->next;
while(node1!=node2)
{
node1=node1->next;
node2=node2->next;
}
}
return node1;
}