剑指offer第二十五题

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

思路:
(1)在原来的链表每个节点后面添加一个节点,该节点下面连接着原来节点的下一个节点,并且该节点的值与前面连着的这个节点值相同,比如A->B->C,变成A->A’->B->B’->C->C’。A,A’; B,B’; C,C’ 的value分别相同
(2)新添加的节点的random分别指向对应的原节点random的下一个节点,什么意思呢,比如说:A->random=C,那么现在A’->random=C’,至此就完成了原来链表的复制,接下来是输出复制出来的链表
(3)将已经做好链表拆分,拆为A->B->C,A’->B’->C’。怎么拆呢,就是将每个节点的next指向其相隔的另一个节点,要注意的是,在断开相邻的两个节点的连接的时候,要先把后一个节点的位置先复制出来,要不待会儿前一个节点指向另外的节点了,后一个节点的位置就丢了。什么意思呢,比如说要断开A->A’的连接,让A->B,那么就要先把A’的指针先存起来(放到一个临时指针里),然后再让A->next指向B,然后再回过头来对A’进行操作,让它重新连接到B’。
具体实现结合下面代码来看:

class Solution {
public:
    RandomListNode* Clone(RandomListNode* pHead)
    {
        //要有这个判断,没有会报错哦
        if(pHead==NULL) return NULL;
        //在每个节点之后插入复制点的节点
        //这个是链表插入节点的操作,很简单
        RandomListNode* headnode=pHead;
        while(headnode)
        {
            RandomListNode* node=new RandomListNode(headnode->label);
            node->next=headnode->next;
            headnode->next=node;
            headnode=node->next;
        }
        //将random指向的节点复制到新加入的节点上
        headnode=pHead;
        while(headnode)
        {
            if(headnode->random)
            {
            //headnode->random连接的是原来节点的random指针对应的节点,再指向next就指向了random后面新添加的节点
            //比如A->random=C,A->random->next=C',这样A'->random就等于C'了
                headnode->next->random=headnode->random->next;
            }
            //下面这句代码要写在if外面,因为headnode->random很可能指向的是NULL,如果指向了NULL,那么就要继续遍历接下来的节点。
            headnode=headnode->next->next;
        }
        //将现在的链表每隔相连
        //这个链表拆除的步骤可以结合我上面将的第三步来看,说一句,这里的clonenode用来保存复制的链表的头结点指针
        RandomListNode* clonenode=pHead->next;
        headnode=pHead;
        while(headnode->next)
        {
            RandomListNode* tmp=headnode->next;
            headnode->next=tmp->next;
            headnode=tmp;
        }
        return clonenode;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值