剑指Offer-26-复杂链表的复制-优化

原创 2015年11月21日 11:58:28

前面文章所使用的方法时间主要花费在定位结点的m_pSibling上面,我们试着在这方面去做优化。
我们还是分为两步:
第一步仍然是复制原始链表上的每个结点N,并创建N’,然后把这些创建出来的结点链接起来。这一次,我们把新创建的每个结点N’链接在原先结点N的后面。
这里写图片描述
代码如下:


void CloneNodes(ComplexListNode *pHead) {
    ComplexListNode* pNode = pHead;
    while(pNode != NULL)
    {
        ComplexListNode* pCloned = new ComplexListNode();
        pCloned->m_nValue = pNode->m_nValue;
        pCloned->m_pNext = pNode->m_pNext;
        pCloned->m_pSibling = NULL;

        pNode->m_pNext = pCloned;

        pNode = pCloned->m_pNext;
    }
}

第二步是设置我们复制出来的链表上的结点的m_pSibling。假设原始链表上的N的m_pSibling指向结点S,那么其对应复制出来的N’是N->m_pNext,同样S’也是S->m_pNext。这就是我们在上一步中把每个结点复制出来的结点链接在原始结点后面的原因。有了这样的链接方式,我们就能在O(1)中就能找到每个结点的m_pSibling了。代码如下:


void ConnectSiblingNodes(ComplexListNode* pHead)
{
    ComplexListNode* pNode = pHead;
    while(pNode != NULL)
    {
        ComplexListNode* pCloned = pNode->m_pNext;
        if(pNode->m_pSibling != NULL)
        {
            pCloned->m_pSibling = pNode->m_pSibling->m_pNext;
        }

        pNode = pCloned->m_pNext;
    }
}

第三步是把这个长链表拆分成两个:把奇数位置的结点链接起来就是原始链表,把偶数位置的结点链接出来就是复制出来的链表。要实现这一步,也不是很难的事情。其对应的代码如下:


ComplexListNode* ReconnectNodes(ComplexListNode* pHead){
    ComplexListNode* pNode = pHead;
    ComplexListNode* pClonedHead = NULL;
    ComplexListNode* pClonedNode = NULL;
    if(pNode != NULL)
    {
        pClonedHead = pClonedNode = pNode->m_pNext;
        pNode->m_pNext = pClonedNode->m_pNext;
        pNode = pNode->m_pNext;
    }
    while(pNode != NULL) {
        pClonedNode->m_pNext = pNode->m_pNext;
        pClonedNode = pClonedNode->m_pNext;

        pNode->m_pNext = pClonedNode->m_pNext;
        pNode = pNode->m_pNext;
    }
    return pClonedHead;
}

我们把上面三步合起来,就是复制链表的完整过程:

ComplexListNode* Clone(ComplexListNode *pHead) {
    CloneNodes(pHead);
    ConnectSiblingNodes(pHead);
    ComplexListNode *pClonedHead = ReconnectNodes(pHead);
    return pClonedHead;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

剑指Offer-26-复杂链表的复制

题目: 有一个复杂链表,其结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任一结点或者NULL。其结点的C++定义如下: struct ComplexN...
  • qing0706
  • qing0706
  • 2015年11月21日 11:27
  • 134

【面试题】剑指Offer-26-复杂链表的复制

题目概述
  • qq_31828515
  • qq_31828515
  • 2017年04月10日 10:41
  • 158

剑指Offer-复杂链表的复制

题目描述输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则...
  • wangyang1354
  • wangyang1354
  • 2017年06月20日 13:08
  • 249

剑指Offer--复杂链表的复制

复制复杂链表
  • strongyoung88
  • strongyoung88
  • 2015年10月20日 20:35
  • 319

剑指offer--复杂链表的复制

题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。 /* public class RandomListNode { in...
  • kangaroo835127729
  • kangaroo835127729
  • 2015年04月11日 22:13
  • 1022

剑指Offer--026-复杂链表的复制

链接 牛客OJ:复杂链表的复制 九度OJ:http://ac.jobdu.com/problem.php?pid=1524 GitHub代码: 026-复杂链表的复制 ...
  • gatieme
  • gatieme
  • 2016年04月23日 20:02
  • 3678

剑指Offer_25_复杂链表的复制

题目描述输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则...
  • ggmfengyangdi
  • ggmfengyangdi
  • 2016年08月17日 09:34
  • 87

剑指offer-26复杂链表的复制

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。 /* struct RandomListNode { int label; ...
  • lw952799980
  • lw952799980
  • 2016年05月26日 22:32
  • 133

剑指offer---复杂链表的复制

题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引...
  • qq_22238021
  • qq_22238021
  • 2017年10月01日 21:22
  • 46

剑指offer-复杂链表的复制

题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。 解题思路(转载自网上): 图 4.8 是一个含有 5 个结点...
  • SoundSlow
  • SoundSlow
  • 2016年03月13日 13:19
  • 574
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:剑指Offer-26-复杂链表的复制-优化
举报原因:
原因补充:

(最多只允许输入30个字)