LeetCode | Copy List with Random Pointer

100 篇文章 0 订阅
13 篇文章 0 订阅

拷贝一个带随机指针的链表

A linked list is given such that each node contains an additional
random pointer which could point to any node in the list or null.

Return a deep copy of the list.

这道题的思路很重要…
首先它要求深度拷贝,所以要求重新开辟空间进行克隆
具体深度拷贝浅度拷贝可以参考这篇文章
http://www.cnblogs.com/vihone/archive/2009/08/16/1546998.html

如果是一般的让我们对一个链表进行拷贝,那直接遍历就好了。
关键在于这些随机指针的处理,万一按照之前的思路,直接拷贝出来了,那我们将无法知道这些随机指针指向的是哪一个节点,gg
于是思路是在原来的每个节点后面,拷贝一个节点并插入,这样就会形成这样的链表
示意图

如此一来,每个节点temp的ramdom域所保存的地址,
就可以通过temp->next->random=temp->random->next;达到完美复制

最后,需要注意一点!!!
原链表要恢复原样…
也就是说最后将两个链表剔除出来的时候,原链表得恢复,这道题提交一开始报了一个奇葩的错误…..modified…之类的,后来才知道是得维护原有指针。
ok那好说,拿两个指针扫就好了。

new_list->next=temp->next;
new_list=new_list->next;
temp->next=temp->next->next;
temp=temp->next;

嗯以上差不多就是这道题…挺难的主要想不到这样处理

/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        RandomListNode root(-1);
        root.next=head;

        //将原链表拷贝一份
        RandomListNode* temp=head;
        while(temp!=NULL){
            RandomListNode *new_node=new RandomListNode(temp->label);
            new_node->next=temp->next;
            temp->next=new_node;
            temp=temp->next->next;
        }

        //将随机指针拷贝出来
        temp=head;
        while(temp!=NULL){
            if(temp->random)
            temp->next->random=temp->random->next;
            temp=temp->next->next;
        }

        //将链表提取出来
        temp=&root;
        RandomListNode* t=head;
        while(t!=NULL){
            temp->next=t->next;
            temp=temp->next;
            //还需要将原表归位
            t->next=t->next->next;
            t=t->next;
        }
        return root.next;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值