两个链表的第一个公共节点
两个链表有一个公共节点,最终会重合到一个链表上
解法一:先用连个指针分别遍历到结尾,如果有共同结尾,就有共同节点 O(2N)
先用链表尾与一种一个链表头连接,形成闭环,再用P1、P2两个指针,一个走一步,一个走两步,直至重合到节点P3,该节点一定是闭环中的一个节点O(N)
以p2点作为开头,再计算该闭环有m个节点O(N)
从另一个表头开始遍历,P1和p2指针相差m步,P1与p2的相交节点,就是入口节点O(N)
空间O(1),其实搞复杂了
注意:两个链表可能没有共同节点
解法二:蛮力算法,用节点数为m的甲链表 去试 节点数为n的乙链表,一个一个试,吼复杂 ,O(MN)
解法三:用两个栈分别保存两个链表所有节点的节点指针,弹出时进行比较,最后一对相同的指针就是指向第一个节点,空间O(M+N)
解法四:先比较两个链表的长度,最长的减去相应的开头,同时遍历,直至两个节点相等 O(M+N+M) 空间O(1),这个最简单了
解法一:
ListNode* FindFirstCommonNode2(ListNode *pHead1, ListNode *pHead2)//diy
{
if (pHead1 == nullptr || pHead2 == nullptr) return nullptr;
ListNode* p1 = pHead1;
ListNode* p2 = pHead2;
while (p1->m_pNext != nullptr)
p1 = p1->m_pNext;
while (p2->m_pNext != nullptr)
p2 = p2->m_pNext;
if (p1 != p2) return nullptr;
ListNode* pEnd = p1;
pEnd->m_pNext = pHead1;
p1 = pHead2;
p2 = pHead2->m_pNext;
if (p2 == nullptr) return pHead2;
while (p1!=p2)
{
p1 = p1->m_pNext;
p2 = p2->m_pNext->m_pNext;
}
int cnt = 0;
p2 = p2->m_pNext;
while (p1 != p2)
{
cnt++;
p2 = p2->m_pNext;
}
cnt++;
p1 = pHead2;
p2 = pHead2;
while (cnt > 0)
{
p2 = p2->m_pNext;
cnt--;
}
while (p1!=p2)
{
p1 = p1->m_pNext;
p2 = p2->m_pNext;
}
pEnd->m_pNext = nullptr;
return p1;
}
解法四
ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2)//diy
{
if (pHead1 == nullptr || pHead2 == nullptr) return nullptr;
ListNode* p1 = pHead1;
ListNode* p2 = pHead2;
int cnt1 = 1;
int cnt2 = 1;
while (p1->m_pNext != nullptr)
{
p1 = p1->m_pNext;
cnt1++;
}
while (p2->m_pNext != nullptr)
{
p2 = p2->m_pNext;
cnt2++;
}
int cnt = 0;
p1 = pHead1;
p2 = pHead2;
if (cnt1>cnt2)
{
cnt = cnt1 - cnt2;
while (cnt > 0)
{
p1 = p1->m_pNext;
cnt--;
}
}
else
{
cnt = cnt2 - cnt1;
while (cnt > 0)
{
p2 = p2->m_pNext;
cnt--;
}
}
while (p1!=p2)
{
if (p1->m_pNext == nullptr || p2->m_pNext == nullptr)
return nullptr;
p1 = p1->m_pNext;
p2 = p2->m_pNext;
}
return p1;
}