/*******************************************************************
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;
}