题目描述
输入两个链表,找出它们的第一个公共结点。
解题思路:首先是暴力法。其次要去想想有没有更好的解法。
利用栈的思想是,以此把两个链表的节点放入两个栈中,然后以此从栈顶取出节点进行比较,如果相同,则弹出该节点,接着比较下一个节点,直到找到最后一个相同的节点。
也可以不用stack来实现。因为有公共节点的链表后边的节点都重合,因此分别计算出两个链表的长度,然后可以求出长链表比短链表长出的长度L,让长链表的指针先走L步,最后,两个指针同时出发遍历,以此比较,直到找到第一个想等的节点。
解题代码:
1.蛮力法 时间复杂度O(M*N)
2.利用stack的解法 时间复杂度O(M+N)
3.利用有公共节点的两个链表的结构特点出发 时间复杂度为O(M+N),不需要用到栈
/*
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;
unsigned int nLength1=GetListLength(pHead1); //得到两个链表的长度
unsigned int nLength2=GetListLength(pHead2);
int nLengthDif=nLength1-nLength2; //假设pHead为长链表
ListNode* pListHeadLong =pHead1;
ListNode* pListHeadShort=pHead2;
if(nLength2>nLength1)
{
pListHeadLong =pHead2;
pListHeadShort=pHead1;
nLengthDif=nLength2-nLength1;
}
//先在长链表上走nLengthDif步,再同时遍历两个链表
for(int i=0; i<nLengthDif; i++)
pListHeadLong=pListHeadLong->next;
while((pListHeadLong!=nullptr)&&(pListHeadShort!=nullptr)&&(pListHeadLong!=pListHeadShort))
{
pListHeadLong = pListHeadLong->next;
pListHeadShort= pListHeadShort->next;
}
ListNode* pFirstCommonNode=pListHeadLong; //此时pListHeadLong==pListHeadShort
return pFirstCommonNode;
}
private:
unsigned int GetListLength(ListNode* pHead)
{
unsigned int i=0;
ListNode* p=pHead;
while(p!=nullptr)
{
i++;
p=p->next;
}
return i;
}
};