剑指Offer26:复杂链表的复制问题

复杂链表的复制问题

问题描述

 * 题目描述:
 *      请实现函数ComplexListNode(ComplexListNode pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点
 *      之外,还有一个m_pSibling指向链表中的任意结点或者NULL。

问题分析

 * 问题分析:
 *      最原始的解法:分两步,第一步复制原始链表上的每一个结点,并用mPnext链接起来;第二步,设置每一个结点的pSibling指针。假设原始链表中的
 *      某个结点N的pSibling指向节点S,由于S的位置在链表中可能在N的前面也可能在N的后面,所以要定位S的位置需要从原始链表的头结点开始找。如果从原始
 *      链表的头结点开始沿着pNext经过s步找到结点S,那么在复制链表上结点N'的pSibling(S')离复制链表的头结点的距离也是沿着pNext指针s步。这样时间复杂度为
 *      o(n^2)。
 *      第二种方法:
 *          还是分两步,第一步仍然是复制原始链表上的每个结点N创建N',然后把这些创建出来的结点用pNext链接起来。同时我们把<N,N'>的配对信息放到一个哈希表中。
 *          第二步还是设置复制链表上每个结点pSibling。如果在原始链表中结点N的mSibling指向结点S,那么在复制链表中,对应的N'应该指向S’。由于有了哈希表,我们可以用o(1)
 *          的时间根据S找到S'。
 *      第三种方法:
 *          第一步仍然是根据原始链表的每一个结点N创建对应的N'。这一次,把N'链接在N的后面;
 *          第二步,设置复制出来的结点pSibling,假设原始链表上的N的pSibling指向结点S,那么其对应复制出来的N'是N的pNext指向的结点,同样
 *          S'也是S的pNext指向的结点。设置pSibling之后的链表。
 *          第三步,把这个长链表拆分成两个链表:把奇数位置的结点用pNext链接起来就是原始链表的位置,把偶数位置的结点用pNext链接起来就是复制出来的链表。
public class Code026 {
    public static ComplexListNode main(String[] args){
        ComplexListNode pHead=new ComplexListNode();
        CloneNodes(pHead);
        ConnectSiblingNodes(pHead);
        return ReconnectNodes(pHead);
    }
    private static void CloneNodes(ComplexListNode pHead){
        ComplexListNode pNode=pHead;
        while (pNode!=null){
            ComplexListNode pCloned=new ComplexListNode();
            pCloned.value=pNode.value;
            pCloned.pNext=pNode.pNext;
            pCloned.pSibling=null;
            pNode.pNext=pCloned;
            pNode=pCloned.pNext;
        }
    }
    private static void ConnectSiblingNodes(ComplexListNode pHead){
        ComplexListNode pNode=pHead;
        while (pNode!=null){
            ComplexListNode pCloned=pNode.pNext;
            if(pNode.pSibling!=null){
                pCloned.pSibling=pNode.pSibling.pNext;
            }
            pNode =pCloned.pNext;
        }
    }
    private static ComplexListNode ReconnectNodes(ComplexListNode pHead){
        ComplexListNode pNode=pHead;
        ComplexListNode pClonedHead=null;
        ComplexListNode pClonedNode=null;
        if(pNode!=null){
            pClonedHead=pClonedNode=pNode.pNext;
            pNode.pNext=pClonedNode.pNext;
            pNode=pNode.pNext;
        }
        while (pNode!=null){
            pClonedNode.pNext=pNode.pNext;
            pClonedNode=pClonedNode.pNext;
            pNode.pNext=pClonedNode.pNext;
            pNode=pNode.pNext;
        }
        return pClonedHead;
    }
    private static class ComplexListNode{
        int value;
        ComplexListNode pNext;
        ComplexListNode pSibling;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值