剑指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;
}

 

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