<剑指offer>面试题52:两个链表的第一个公共节点

题目描述

  • 输入两个链表,找出它们的第一个公共节点。

题目解读

  • 方法一就是蛮力法,分别遍历第一个链表的每个结点和第二个链表的所有结点进行比较,遍历第二个链表的每个结点和第一个链表的所有结点进行比较。时间复杂度为O(mn).
  • 方法二:若两个单向链表有公共节点,则说明这两个链表从某一个节点开始,它们的后继节点都指向同一个节点。因为每个单向链表的节点都只有一个后继节点,故从第一个公共节点开始,它们所有的节点都是重合的。如下图所示:
    两个链表在值为6的节点处交汇

    可以先遍历一次得到每个链表的长度,然后长链表先走多出的若干步。如上图所示:链表长度分别为5和4,长链表与短链表相比多一个节点,然后让长链表先走一步,到达节点2.接下来分别从节点2和节点4出发同时遍历两个结点,直到找到它们第一个相同的节点6.此时的时间复杂度为o(m+n)

代码部分

  • 前期准备工作(链表的创建和输出)
ListNode* createList(int *array,int len)
    {
        ListNode *head,*tail,*p;
        head = tail = NULL;
        for(int i=0;ival = array[i];
            p->next = NULL;
            if(head==NULL)
            {
                head = p;
                tail = head;
            }
            else
            {
                tail->next = p;
                //tail = p;
            }
            tail = p;
        }
        return head;
    }
    
    void printT(ListNode *head)
    {
        while(head)
        {
            cout<val<<" ";
            head = head->next;
        }
        cout<
  • 计算每个链表的长度
int GetListLength(ListNode* head)
    {
        int nLength = 0;
        ListNode *pNode = NULL;
        pNode = head;
        while(pNode != NULL)
        {
            ++nLength;
            pNode = pNode->next;
        }
        return nLength;
    }
  • 确定长链表和短链表,然后让长链表先走若干步,最后两个链表一起移动直到表尾。若移动过程中,两个结点相等,那么说明找到第一个公共节点
ListNode* FindFirstCommonNode(ListNode* pHead1,ListNode* pHead2)
    {
        //寰楀埌涓や釜閾捐〃鐨勯暱搴?
        int nLength1,nLength2;
        nLength1 = GetListLength(pHead1);
        nLength2 = GetListLength(pHead2);
        int nLengthDif = 0;
        //cout<nLength1)
        {
            pListHeadLong = pHead2;
            pListHeadShort= pHead1;
            nLengthDif = nLength2-nLength1;
        }
        else
        {
            pListHeadLong = pHead1;
            pListHeadShort= pHead2;
            nLengthDif = nLength1-nLength2;
        }
        
        //让长链表先前进nLengthDif步
        for(int i=0;inext;
        }
      
        while((pListHeadLong != NULL) && (pListHeadShort != NULL) && (pListHeadLong->val != pListHeadShort->val))
        {
            pListHeadLong = pListHeadLong->next;
            pListHeadShort= pListHeadShort->next;
        }
        
        ListNode *pFirstCommonNode = NULL;
        pFirstCommonNode = pListHeadLong;
        cout<val<

你可能感兴趣的:(<剑指offer>面试题52:两个链表的第一个公共节点)