题意
输入两个链表,找出它们的第一个公共节点。如下面的两个链表:
解法1—双指针
假设链表A的长度为 L1+C;链表B的长度为 L2+C。C为两链表的公共部分长度。
因此,我们使用两个指针 node1
,node2
分别指向两个链表 headA
,headB
的头结点,然后同时分别逐结点遍历,当 node1
到达链表 headA
的末尾时,重新定位到链表 headB
的头结点;当 node2
到达链表headB
的末尾时,重新定位到链表 headA
的头结点。这样,当它们相遇时,所指向的结点就是第一个公共结点。
node1走的长度:L1+C+L2。node2走的长度:L2+C+L1。
若两个链表没有公共部分,即 C=0 ,那么node1和node2同时指向null。
C++实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution
{
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB)
{
ListNode* node1=headA;
ListNode* node2=headB;
while(node1!=node2)
{
node1 = node1!=NULL?node1->next:headB;
node2 = node2!=NULL?node2->next:headA;
}
return node1;
}
};
解法2—哈希表
在遍历链表A的时候,依次将节点的地址(不是值)加入哈希表中。然后再遍历链表B,看B中是否有节点在哈希表中找到,如果找到就返回该节点,否则返回NULL。
C++实现
class Solution
{
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB)
{
// ListNode* node1=headA;
// ListNode* node2=headB;
// while(node1!=node2)
// {
// node1 = node1!=NULL?node1->next:headB;
// node2 = node2!=NULL?node2->next:headA;
// }
// return node1;
unordered_set<ListNode *> visited;
ListNode *temp = headA;
while (temp != nullptr)
{
visited.insert(temp);
temp = temp->next;
}
temp = headB;
while (temp != nullptr)
{
if (visited.count(temp))
{
return temp;
}
temp = temp->next;
}
return nullptr;
}
};