题目
输入两个链表,找出它们的第一个公共结点。
思路
这道题和160.Intersection of Two Linked Lists是一样的。都是求两个链表的第一个公共结点。
公共结点的样子:
上图就是一个有公共结点的例子,在公共结点之后,两个链表指针指向的地址是相同的。
这道题有两个解法。
方法一:
我们可以把两个链表拼接起来,一个pHead1在前pHead2在后,一个pHead2在前pHead1在后。这样,生成了两个相同长度的链表,那么我们只要同时遍历这两个表,就一定能找到公共结点。时间复杂度O(m+n),空间复杂度O(m+n)。
方法二:
我们也可以先让把长的链表的头砍掉,让两个链表长度相同,这样,同时遍历也能找到公共结点。此时,时间复杂度O(m+n),空间复杂度为O(MAX(m,n))。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
//把长度链表截成和短的一样长
ListNode* FindFirstCommonNode( ListNode* head1, ListNode* head2)
{
if (head1 == nullptr || head2 == nullptr)
return nullptr;
int len1 = getLen(head1);
int len2 = getLen(head2);
if (len1 <= len2)
{
int i = len2 - len1;
while( i--)
head2 = head2->next;
while (head1 != nullptr)
{
if (head1->val == head2->val)
return head1;
else
{
head1 = head1->next;
head2 = head2->next;
}
}
}
else
{
int i = len1 - len2;
while (i--)
head1 = head1->next;
while(head2 != nullptr)
{
if (head1->val == head2->val)
return head1;
else
{
head1 = head1->next;
head2 = head2->next;
}
}
}
return nullptr;
}
private:
int getLen(ListNode *node)
{
if (node == nullptr)
return 0;
int count = 0;
while (node != nullptr)
{
count++;
node = node->next;
}
return count;
}
};
代码可以写的再简练一点:
class Solution {
public:
//把长度链表截成和短的一样长
ListNode* FindFirstCommonNode( ListNode* head1, ListNode* head2)
{
if (head1 == nullptr || head2 == nullptr)
return nullptr;
int len1 = getLen(head1);
int len2 = getLen(head2);
ListNode *longnode = head1; //默认head1长,否则后续会调整
ListNode *shortnode = head2;
int diff = len1 - len2;
if (len1 < len2)
{
longnode = head2;
shortnode = head1;
diff = len2 - len1;
}
while (diff--)
longnode = longnode->next;
while (shortnode != nullptr)
{
if (longnode->val == shortnode->val)
return longnode;
else
{
longnode = longnode->next;
shortnode = shortnode->next;
}
}
return nullptr;
}
private:
int getLen(ListNode *node)
{
if (node == nullptr)
return 0;
int count = 0;
while (node != nullptr)
{
count++;
node = node->next;
}
return count;
}
};