两个链表第一个公共节点
方法一 :
先让长的链表的指针先走长的之差的步数, 两个再一起走, 如果相遇就是第一个公共节点
如果没交点, 就都走到空
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution
{
public:
ListNode *FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2 )
{
// 长的链表先走 len1-len2 步, 再一起走, 相遇了, 就是第一个公共节点
if(pHead1 == NULL || pHead2 == NULL)
return NULL;
ListNode *pl1 = pHead1;
ListNode *pl2 = pHead2;
int len1 = 0;
int len2 = 0;
while(pl1 != NULL)
{
++len1;
pl1 = pl1->next;
}
while(pl2 != NULL)
{
++len2;
pl2 = pl2->next;
}
// 复位指针到头节点
pl1 = pHead1;
pl2 = pHead2;
int dif_len = 0;
if(len1 > len2)
{
// 如果第一条链表长, 就让第一条先走 len1 - len2 步
dif_len = len1 - len2;
while(dif_len--)
{
pl1 = pl1->next;
}
}
else
{
// 如果第二条链表长, 就让第二条先走 len2 - len1 步
dif_len = len2 - len1;
while(dif_len--)
{
pl2 = pl2->next;
}
}
// 再让两个一起走
while(pl1 != NULL)
{
if(pl1 == pl2)
{
return pl1;
}
pl1 = pl1->next;
pl2 = pl2->next;
}
return NULL;
}
};
方法二:
不用计算长度, 两个指针分别指向两个链表, 只要两个指针不相等就一直走
如果一个指针走到空, 就让它指向另一条链表的头, 再继续走
如果两个链表相交, 两个指针肯定会相遇
如果不相交, 两个链表都走到空, 循环结束, 返回空
如上图所示, l1 长为 10, l2 长为 15
两个先一起走, 当短的走到空的时候, 长的刚走到两个的交点处, 然后让短的指针指向长的链表, 再一起走, 长的指针到空, 这时短的指针已经走到了两个链表长度差值的地方, 再让长的指针指向短的链表, 再一起走, 相当于两个指针就在同一起跑线了, 再往下走, 肯定会相遇
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1 == NULL || pHead2 == NULL)
return NULL;
ListNode* pl1 = pHead1;
ListNode* pl2 = pHead2;
while(pl1 != pl2)
{
if(pl1 != NULL)
{
pl1 = pl1->next;
}
else
{
pl1 = pHead2;
}
if(pl2 != NULL)
{
pl2 = pl2->next;
}
else
{
pl2 = pHead1;
}
}
return pl1;
}
};