zoukankan      html  css  js  c++  java
  • 【面试题037】两个链表的第一个公共结点

    【面试题037】两个链表的第一个公共结点
    题目:
        输入两个链表,找出它们的第一个公共结点。链表结点定义如下:
    1
    2
    3
    4
    5
     
    struct ListNode
    {
        int m_nKey;
        ListNode *m_pNext;
    }
     
    思路一:
        蛮力法,在第一个链表上面遍历,对每个遍历到的结点,我们都在第二个链表上面顺序遍历。
    如果第二个链表上面有和第一个链表上面当前遍历到的结点相同的结点,那么就找到了相同的结点。
    ——时间复杂度是 O(m*n)。
     
    思路二:
        遍历结点分别入两个栈当中,同时对比top(),如果相同那么同时出栈,知道找到最后一个相同的结点。
    ——辅助空间为O(m+n),时间复杂度为O(m+n)。
     
    思路三:
        先分别遍历两个链表得到两个链表的长度,那么就知道那个链表比较长,以及比短的长了多少。
    在第二次遍历的时候先在长的链表上面多走那么多步。接着同时在两个链表上面同时遍历。
    找到的第一个相同的结点 就是它们的第一个公共的结点。
    ——时间复杂度是O(m+n),但是我们不需要额外的存储空间啦。
     
     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    #include <iostream>
    #include "List.h"
    using namespace std;


    unsigned int GetListLength(ListNode *pHead)
    {
        unsigned int nlength = 0;
        ListNode *pNode = pHead;
        while (pNode != NULL)
        {
            ++ nlength;
            pNode = pNode->m_pNext;
        }
        return nlength;
    }

    ListNode *FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2)
    {
        unsigned int nLength1 = GetListLength(pHead1);
        unsigned int nLength2 = GetListLength(pHead2);

        int nLengthDif = nLength1 - nLength2;
        ListNode *pListHeadLong = pHead1;
        ListNode *pListHeadShort = pHead2;
        if (nLength2 > nLength1)
        {
            pListHeadLong = pHead2;
            pListHeadShort = pHead1;
            nLengthDif = nLength2 - nLength1;
        }

        for (int i = 0; i < nLengthDif; ++i)
        {
            pListHeadLong = pListHeadLong->m_pNext;
        }

        while ( (pListHeadLong != NULL) && (pListHeadShort != NULL) && (pListHeadLong != pListHeadShort) )
        {
            pListHeadLong = pListHeadLong->m_pNext;
            pListHeadShort = pListHeadShort->m_pNext;
        }

        ListNode *pFirstCommonNode = pListHeadLong;

        return pFirstCommonNode;
    }


    // 第一个公共结点在链表中间
    // 1 - 2 - 3 
    //            6 - 7
    //     4 - 5 /
    int main()
    {

        ListNode *pNode1 = CreateListNode(1);
        ListNode *pNode2 = CreateListNode(2);
        ListNode *pNode3 = CreateListNode(3);
        ListNode *pNode4 = CreateListNode(4);
        ListNode *pNode5 = CreateListNode(5);
        ListNode *pNode6 = CreateListNode(6);
        ListNode *pNode7 = CreateListNode(7);

        ConnectListNodes(pNode1, pNode2);
        ConnectListNodes(pNode2, pNode3);
        ConnectListNodes(pNode3, pNode6);
        ConnectListNodes(pNode4, pNode5);
        ConnectListNodes(pNode5, pNode6);
        ConnectListNodes(pNode6, pNode7);

        ListNode *ans = FindFirstCommonNode(pNode1, pNode4);
        cout << ans->m_nValue << endl;

        //DestroyList(pNode1);
        //DestroyList(pNode4);
        return 0;
    }
     
    List.h
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    #ifndef _LIST_H_
    #define _LIST_H_

    struct ListNode
    {
        int       m_nValue;
        ListNode *m_pNext;
    };

    ListNode *CreateListNode(int value);
    void ConnectListNodes(ListNode *pCurrent, ListNode *pNext);
    void PrintListNode(ListNode *pNode);
    void PrintList(ListNode *pHead);
    void DestroyList(ListNode *pHead);
    void AddToTail(ListNode **pHead, int value);
    void RemoveNode(ListNode **pHead, int value);

    #endif //_LIST_H_
    List.cpp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
     
    #include "list.h"
    #include <stdio.h>
    #include <stdlib.h>

    ListNode *CreateListNode(int value)
    {
        ListNode *pNode = new ListNode();
        pNode->m_nValue = value;
        pNode->m_pNext = NULL;

        return pNode;
    }

    void ConnectListNodes(ListNode *pCurrent, ListNode *pNext)
    {
        if(pCurrent == NULL)
        {
            printf("Error to connect two nodes. ");
            exit(1);
        }

        pCurrent->m_pNext = pNext;
    }

    void PrintListNode(ListNode *pNode)
    {
        if(pNode == NULL)
        {
            printf("The node is NULL ");
        }
        else
        {
            printf("The key in node is %d. ", pNode->m_nValue);
        }
    }

    void PrintList(ListNode *pHead)
    {
        printf("PrintList starts. ");

        ListNode *pNode = pHead;
        while(pNode != NULL)
        {
            printf("%d ", pNode->m_nValue);
            pNode = pNode->m_pNext;
        }

        printf(" PrintList ends. ");
    }

    void DestroyList(ListNode *pHead)
    {
        ListNode *pNode = pHead;
        while(pNode != NULL)
        {
            pHead = pHead->m_pNext;
            delete pNode;
            pNode = pHead;
        }
    }

    void AddToTail(ListNode **pHead, int value)
    {
        ListNode *pNew = new ListNode();
        pNew->m_nValue = value;
        pNew->m_pNext = NULL;

        if(*pHead == NULL)
        {
            *pHead = pNew;
        }
        else
        {
            ListNode *pNode = *pHead;
            while(pNode->m_pNext != NULL)
                pNode = pNode->m_pNext;

            pNode->m_pNext = pNew;
        }
    }

    void RemoveNode(ListNode **pHead, int value)
    {
        if(pHead == NULL || *pHead == NULL)
            return;

        ListNode *pToBeDeleted = NULL;
        if((*pHead)->m_nValue == value)
        {
            pToBeDeleted = *pHead;
            *pHead = (*pHead)->m_pNext;
        }
        else
        {
            ListNode *pNode = *pHead;
            while(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value)
                pNode = pNode->m_pNext;

            if(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value)
            {
                pToBeDeleted = pNode->m_pNext;
                pNode->m_pNext = pNode->m_pNext->m_pNext;
            }
        }

        if(pToBeDeleted != NULL)
        {
            delete pToBeDeleted;
            pToBeDeleted = NULL;
        }
    }
     
  • 相关阅读:
    数据库的基本操作
    这是数据库的知识了
    这就全都是了解的东西啦
    互斥锁
    我只会用threading,我菜
    violet
    网络编程II
    网络编程
    这是网络编程的一小步,却是我的一大步
    莫比乌斯反演(一)从容斥到反演
  • 原文地址:https://www.cnblogs.com/codemylife/p/3751987.html
Copyright © 2011-2022 走看看