/*******************************************************************
Copyright(c) 2016, Tyrone Li
All rights reserved.
*******************************************************************/
// 作者:TyroneLi
//
/*
Q:
兩個鏈表的第一個公共結點:
輸入兩個鏈表,找出他們的第一個公共結點。
S:
1. 根據單向鏈表的定義可以知道,遍歷鏈表只能從前往後遍歷,並且連個鏈表有公共結點,
也就是從某個節點開始,兩個鏈表的結點上next指針指向都一樣。如果是從後往前遍歷,
那麼可以找到最後一個公共結點,同時也是本題要求的第一個公共結點。這裏可以採用
棧的方法後入先出,分別用兩個輔助棧存儲從兩個鏈表中遍歷的結點然後依次彈出,直到
遇到第一個公共的結點。
2. 這裏不用採取像1那樣的用很大的棧空間換時間的方法,兩個鏈表有公共結點,說明從某
個結點開始兩個鏈表擁有共同的部分鏈表。假設兩個鏈表長度差距N,那麼也就是如果用兩
個指針分別指向兩個鏈表,比較長的那個鏈表先走N步,然後兩個指針在一起依次遍歷,這
時候兩個鏈表就可以同時到達共同結點;該方法也不用藉助額外的棧內存空間。
*/
#include "../utils/List.h"
#include <iostream>
#include <cstdio>
#include <cstdlib>
int getLength(ListNode*pHead)
{
unsigned int length = 0;
ListNode*pNode = pHead;
while(pNode != nullptr)
{
++length;
pNode = pNode->m_pNext;
}
return length;
}
ListNode*findCommonListNode(ListNode*pHead_1, ListNode*pHead_2)
{
if(pHead_1 == nullptr || pHead_2 == nullptr)
return nullptr;
int length_1 = getLength(pHead_1);
int length_2 = getLength(pHead_2);
int diff = (length_2 < length_1)?(length_2 - length_1):(length_1 - length_2);
ListNode*pNode_short = pHead_1;
ListNode*pNode_long = pHead_2;
if(length_1 > length_2)
{
pNode_short = pHead_2;
pNode_long = pHead_1;
}
int cnt = 0;
while((cnt++) < diff)
pNode_long = pNode_long->m_pNext;
while(pNode_long != nullptr && pNode_short != nullptr && pNode_long != pNode_short)
{
pNode_long = pNode_long->m_pNext;
pNode_short = pNode_short->m_pNext;
}
ListNode*rst = pNode_long;
return rst;
}
void test_1()
{
std::cout << "Test 1" << std::endl;
ListNode*L1 = createListNode(1);
ListNode*L2 = createListNode(-1);
ListNode*L1_1 = createListNode(2);
ListNode*L1_2 = createListNode(3);
ListNode*L2_1 = createListNode(-2);
ListNode*L2_2 = createListNode(-3);
ListNode*L3 = createListNode(10);
ListNode*L4 = createListNode(11);
connectListNodes(L1, L1_1);
connectListNodes(L1_1, L1_2);
connectListNodes(L1_2, L3);
connectListNodes(L3, L4);
connectListNodes(L2, L2_1);
connectListNodes(L2_1, L2_2);
connectListNodes(L2_2, L3);
connectListNodes(L3, L4);
std::cout << "Print List 1" << std::endl;
printList(L1);
std::cout << "Print List 2" << std::endl;
printList(L2);
ListNode*pNode = findCommonListNode(L1, L2);
std::cout << "Found common Node : " << std::endl;
printListNode(pNode);
}
void test_2()
{
std::cout << "Test 2" << std::endl;
ListNode*L1 = createListNode(1);
ListNode*L2 = createListNode(-1);
ListNode*L1_1 = createListNode(2);
ListNode*L1_2 = createListNode(3);
ListNode*L2_1 = createListNode(-2);
ListNode*L2_2 = createListNode(-3);
ListNode*L3 = createListNode(10);
connectListNodes(L1, L1_1);
connectListNodes(L1_1, L1_2);
connectListNodes(L1_2, L3);
connectListNodes(L2, L2_1);
connectListNodes(L2_1, L2_2);
connectListNodes(L2_2, L3);
std::cout << "Print List 1" << std::endl;
printList(L1);
std::cout << "Print List 2" << std::endl;
printList(L2);
ListNode*pNode = findCommonListNode(L1, L2);
std::cout << "Found common Node : " << std::endl;
printListNode(pNode);
}
void test_3()
{
std::cout << "Test 3" << std::endl;
ListNode*L1 = createListNode(1);
ListNode*L1_1 = createListNode(2);
ListNode*L1_2 = createListNode(3);
ListNode*L3 = createListNode(10);
ListNode*L4 = createListNode(11);
connectListNodes(L1, L1_1);
connectListNodes(L1_1, L1_2);
connectListNodes(L1_2, L3);
connectListNodes(L3, L4);
std::cout << "Print List 1" << std::endl;
printList(L1);
std::cout << "Print List 2" << std::endl;
printList(L1);
ListNode*pNode = findCommonListNode(L1, L1);
std::cout << "Found common Node : " << std::endl;
printListNode(pNode);
}
void test_4()
{
std::cout << "Test 4" << std::endl;
ListNode*L1 = createListNode(1);
ListNode*L2 = createListNode(-1);
ListNode*L1_1 = createListNode(2);
ListNode*L1_2 = createListNode(3);
ListNode*L2_1 = createListNode(-2);
ListNode*L2_2 = createListNode(-3);
connectListNodes(L1, L1_1);
connectListNodes(L1_1, L1_2);
connectListNodes(L2, L2_1);
connectListNodes(L2_1, L2_2);
std::cout << "Print List 1" << std::endl;
printList(L1);
std::cout << "Print List 2" << std::endl;
printList(L2);
ListNode*pNode = findCommonListNode(L1, L2);
std::cout << "Found common Node : " << std::endl;
printListNode(pNode);
}
void test_findCommonListNode()
{
test_1();
test_2();
test_3();
test_4();
}
int main(int argc, char**argv)
{
test_findCommonListNode();
return 0;
}