#160 Intersection of Two Linked Lists
求两个链表的公共节点。
1、分别遍历两个链表,求各自长度。然后求长度差,并让长的先走长度差这么多步,然后同时开始走,判断每个结点是否相等。
(考虑到公共节点之后的每个结点一定是相等的,所以两个有公共节点的链表一定是前面不同。)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//首先遍历两个链表,分别求出长度
if(headA==nullptr||headB==nullptr)
return nullptr;
ListNode* headAtemp=headA;
int Alength=0;
while(headAtemp)
{
headAtemp=headAtemp->next;
Alength++;
}
ListNode* headBtemp=headB;
int Blength=0;
while(headBtemp)
{
headBtemp=headBtemp->next;
Blength++;
}
//重新指向首地址
headAtemp=headA;
headBtemp=headB;
if(Alength>Blength)
{
//A先走Alength-Blength步
int gaplength=Alength-Blength;
while(gaplength--)
{
headAtemp=headAtemp->next;
}
while(Blength--)
{
if(headAtemp==headBtemp)
return headAtemp;
headAtemp=headAtemp->next;
headBtemp=headBtemp->next;
}
}
else
{
int gaplength=Blength-Alength;
while(gaplength--)
{
headBtemp=headBtemp->next;
}
while(Alength--)
{
if(headAtemp==headBtemp)
return headAtemp;
headAtemp=headAtemp->next;
headBtemp=headBtemp->next;
}
}
return nullptr;
}
};
2、双指针法
让pA和pB分别指向链表A和B的首地址。同时开始访问,一旦一个指针到达末尾,比如pA到达末尾,则将指针指向链表B的首地址,继续遍历,同理pB到达末尾,则将指针指向链表A的首地址,继续遍历。当pA==pB则返回。
这里相当于大家都一共要走A+B链表长度这么长。而如果有公共节点的话,后面那段肯定是公共的。当两个指针同时到达末尾,则没有公共节点。
例如:A=[1,3,5,7,9] B=[2,4,7,9]
则pB相当于要走[2,4,7,9,1,3,5,7,9] pA相当于要走[1,3,5,7,9,2,4,7,9] 注意有公共节点,7,9,也就是说后面一定会遇到!
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//首先遍历两个链表,分别求出长度
if(headA==nullptr||headB==nullptr)
return nullptr;
ListNode* cur1=headA;
ListNode* cur2=headB;
while(cur1!=cur2)
{
cur1=cur1?cur1->next:headB;
cur2=cur2?cur2->next:headA;
}
return cur1;
}
};
3、哈希表
遍历A,将A的各个节点储存起来。
遍历B,查看哈希表内是否已有指针。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//首先遍历两个链表,分别求出长度
if(headA==nullptr||headB==nullptr)
return nullptr;
//因为肯定不是循环的,也就是说指针不会有重复。所以用set
set<ListNode*>hash_table;
ListNode* cur1=headA;
while(cur1)
{
hash_table.insert(cur1);
cur1=cur1->next;
}
ListNode*cur2=headB;
while(cur2)
{
if(hash_table.find(cur2)!=hash_table.end())
return cur2;
else
cur2=cur2->next;
}
return nullptr;
}
};