题目描述
输入两个链表,找出它们的第一个公共结点。
分析:总体来说有很多种方法,比如说最笨的循环遍历,拿第一个链表的所有指针跟第二个链表的所有指针去比较,复杂度为O(mn),还有比较好一点的就是,因为是单向链表,所以在公共结点之后两个链表是重合的,所以我们只需要从链表尾部开始倒着找就可以了,有两种方法,一种是利用栈,比较然后弹栈就行,第二种就是遍历链表得到两个链表的长度,然后让长的链表先走m-n步,然后一起走就行了。但是恕我直言,不是我针对谁,而是这些方法都是垃圾!自从看了大神的代码,再也回不去了,啥也不说了,上代码,来自牛油selfboot的代码,这位也是从leetcode上得到的。
大神的代码:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode* p1=pHead1;
ListNode* p2=pHead2;
while(p1!=p2){
p1=(p1==NULL?pHead2:p1->next);
p2=(p2==NULL?pHead1:p2->next);
}
return p1;
}
};
附上求长度的代码来反衬大神代码的简洁:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode* p1=pHead1;
ListNode* p2=pHead2;
int len1=0,len2=0;
if(p1==NULL||p2==NULL)
return NULL;
while(p1!=NULL){
len1++;
p1=p1->next;
}
while(p2!=NULL){
len2++;
p2=p2->next;
}
p1=pHead1;
p2=pHead2;
if(len1>len2){
for(int i=0;i<len1-len2;i++)
p1=p1->next;
}
if(len2>len1){
for(int j=0;j<len2-len1;j++)
p2=p2->next;
}
while(p1!=p2){
p1=p1->next;
p2=p2->next;
}
return p1;
}
};