劍指offer-兩個鏈表第一個公共節點

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章