题目描述
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
思路1:分别求出两链表表长,计算差值dist,让长的先走dist,然后两链表同时走,找到第一个相同节点。
/*
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 == nullptr || pHead2 == nullptr)
return nullptr;
int l1=0;
int l2=0;
ListNode* node1=pHead1;
ListNode* node2=pHead2;
while (node1 != nullptr){
node1=node1->next;
l1++;
}
while (node2 != nullptr){
node2=node2->next;
l2++;
}
int dist=abs(l2-l1);
if(l2>l1){
while (dist--)
pHead2=pHead2->next;
}else{
while (dist--)
pHead1=pHead1->next;
}
while (pHead1!= nullptr){
if(pHead1==pHead2)
return pHead1;
pHead1=pHead1->next;
pHead2=pHead2->next;
}
return nullptr;
}
};
思路2:
1)若有链表为空,则返回nullptr;
2)若长度相等且有公共节点,则第一次遍历就能找到;
3)若长度相等且无公共节点,则当两链表分别指向尾部nullptr时,返回nullptr;
4)若长度不等且有公共节点,则短链表指针先走完,指向长链表头结点,头链表走完,再指向短链表头结点,第一次遍历可知道相差dist,第二次遍历就可得到第一个公共节点;
5)若长度不等且无公共节点,则第二次遍历指向尾部nullptr时返回。
【参考大神的代码】
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode* node1 = pHead1;
ListNode* node2 = pHead2;
while (node1 != node2){
node1 = (node1 == nullptr ? pHead2 : node1->next);
node2 = (node2 == nullptr ? pHead1 : node2->next);
}
return node1;
}
};
思路3:双栈法,时间和空间复杂度均为O(m+n)。分别把两个链表的节点放入两个栈,从链表尾向前进行比较,返回最后一个相同的节点。
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1== nullptr || pHead2== nullptr)
return nullptr;
stack<ListNode*> st1;
stack<ListNode*> st2;
while (pHead1 != nullptr){
st1.push(pHead1);
pHead1=pHead1->next;
}
while (pHead2 != nullptr){
st2.push(pHead2);
pHead2=pHead2->next;
}
ListNode* result = nullptr;
while (!st1.empty() && !st2.empty() && st1.top()==st2.top()){
result = st1.top(); //注意:找到第一个公共节点,但是公共节点后的所有相同节点都需要存入链表!
st1.pop();
st2.pop();
}
return result;
}
};
思路4:hasnMap 【方法4、5、6思路类似,只是熟练及区分下STL的使用】
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1== nullptr || pHead2== nullptr)
return nullptr;
unordered_map<ListNode*,int> hashmp;
while (pHead1!= nullptr){
hashmp[pHead1] = pHead1->val; //此处也可以hashmp[pHead1] = 1;
pHead1=pHead1->next;
}
while (pHead2!= nullptr){
if(hashmp.find(pHead2)!=hashmp.end())
return pHead2;
pHead2=pHead2->next;
}
return nullptr;
}
};
思路5:Set
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1== nullptr || pHead2== nullptr)
return nullptr;
set<int> setnode;
while (pHead1!= nullptr){
setnode.insert(pHead1->val);
pHead1=pHead1->next;
}
while (pHead2!= nullptr){
if(find(setnode.begin(),setnode.end(),pHead2->val)!=setnode.end())
return pHead2;
pHead2=pHead2->next;
}
return nullptr;
}
};
思路6:Map
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1== nullptr || pHead2== nullptr)
return nullptr;
map<ListNode*,int> mp;
while (pHead1!= nullptr){
mp[pHead1]=1;
pHead1=pHead1->next;
}
while (pHead2!= nullptr){
if(mp.find(pHead2)!=mp.end())
return pHead2;
pHead2=pHead2->next;
}
return nullptr;
}
};