两个链表

参考:http://zhedahht.blog.163.com

  1. 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是按照增序排列的。
  2. 输入两个单链表(无环),找出他们的第一个公共节点。
  3. 判断两个单链表(可能有环)是否相交。

1、思路:

  类似与归并排序,但是这里只需要修改指针指向,不需要另辟空间,通过递归的方式,从后往前拼接链表。

《两个链表》
《两个链表》
MergeList

 1 ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
 2 {
 3     if(pHead1 == NULL)
 4         return pHead2;
 5     else if(pHead2 == NULL)
 6         return pHead1;
 7 
 8     ListNode* pMergedHead = NULL;
 9 
10     if(pHead1->m_nValue < pHead2->m_nValue)
11     {
12         pMergedHead = pHead1;
13         pMergedHead->m_pNext = Merge(pHead1->m_pNext, pHead2);
14     }
15     else
16     {
17         pMergedHead = pHead2;
18         pMergedHead->m_pNext = Merge(pHead1, pHead2->m_pNext);
19     }
20 
21     return pMergedHead;
22 }

 

2、思路:

  如果有公共节点,则最后一个节点肯定是,再倒序回去就能找到第一个公共节点。采用“栈”,这样时间复杂度是O(m+n),空间复杂度是O(m+n)。如果预先计算两个链表的长度,记录长度差,然后先让长链表的指针率先前进长度差步,再两个指针同时前进就能找到第一个公共点,时间复杂度没有变,空间复杂度是O(1)。

《两个链表》
《两个链表》
FindFirstCommonNode

 1 unsigned int GetListLength(ListNode* pHead);
 2 
 3 ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2)
 4 {
 5     // 得到两个链表的长度
 6     unsigned int nLength1 = GetListLength(pHead1);
 7     unsigned int nLength2 = GetListLength(pHead2);
 8     int nLengthDif = nLength1 - nLength2;
 9  
10     ListNode* pListHeadLong = pHead1;
11     ListNode* pListHeadShort = pHead2;
12     if(nLength2 > nLength1)
13     {
14         pListHeadLong = pHead2;
15         pListHeadShort = pHead1;
16         nLengthDif = nLength2 - nLength1;
17     }
18  
19     // 先在长链表上走几步,再同时在两个链表上遍历
20     for(int i = 0; i < nLengthDif; ++ i)
21         pListHeadLong = pListHeadLong->m_pNext;
22  
23     while((pListHeadLong != NULL) && 
24         (pListHeadShort != NULL) &&
25         (pListHeadLong != pListHeadShort))
26     {
27         pListHeadLong = pListHeadLong->m_pNext;
28         pListHeadShort = pListHeadShort->m_pNext;
29     }
30  
31     // 得到第一个公共结点
32     ListNode* pFisrtCommonNode = pListHeadLong;
33  
34     return pFisrtCommonNode;
35 }
36 
37 unsigned int GetListLength(ListNode* pHead)
38 {
39     unsigned int nLength = 0;
40     ListNode* pNode = pHead;
41     while(pNode != NULL)
42     {
43         ++ nLength;
44         pNode = pNode->m_pNext;
45     }
46  
47     return nLength;
48 }

 

3、思路:

  先判断带不带环,如果其中一个带环,另一个不带环,则肯定不想交;如果都不带环,就判断尾节点是否相等;如果都带环,则判断一链表上俩指针相遇的那个节点,在不在另一条链表上。

  

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/wangpengjie/archive/2013/04/10/3012131.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞