leetcode-Copy List with Random Pointer

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.

链表数据结构如下所示:

/**
 * 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) {}
 * };
 */

要拷贝一个链表,这个链表跟平时见到的链表不太一样,就是每个节点还有一个成员random,可能是NULL,也可能指向链表中的任何一个节点。

那应该怎么拷贝呢?就是根据原链表的节点构造新链表的节点,但是新链表节点的random值要指向的是新链表中与原链表节点对应的节点。

第一种方案是可以先一个一个节点拷贝,不管random成员。构造完毕后,要改变新链表节点们的random值啦。从头开始扫描原链表,确定每个节点random的值,如果不是NULL,说明要对新链表节点的random赋值,那该如何赋值呢?肯定不是直接赋值为原链表的random值啦,要赋值为与原链表random指向的节点对应的新节点啦。那怎么知道原链表的节点对应的新节点呢,只要在拷贝原链表的每个节点过程中存储对应的新节点就行,STL的map容器这么好用就用它啦。

第二种方案是要拷贝原链表的每个节点时,搜索对应的新节点是否已经构造过,如果构造了就不用再new啦,如果没有构造,那么需要构造出新节点,然后要存储原节点与新节点的对应关系。如果原节点的random指针不为NULL,那么我们再检查random指向的节点对应的新节点是否已经被构造,如果已经构造过了,那么赋值为那个构造的节点就行啦,如果没有被构造,那么就构造新节点,再把映射关系存储下来。

class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        RandomListNode *new_head, *p, *curr, *next;
        map<RandomListNode*, RandomListNode*> mm;
        
        new_head = NULL;
        p = head;
        
        while (p != NULL) {
            next = new RandomListNode(p->label);
            
            if (new_head == NULL) {
                new_head = next;
            } else {
                curr->next = next;
            }
            
            mm.insert(make_pair(p, next));   // original list node 'p' map to new list node 'next'
            curr = next;
            p = p->next;
        }
        
        p = head;
        curr = new_head;
        
        /* after map the node pointers of original list into new pointers of new list, 
        we assign random pointers of new list nodes */
        while (p != NULL) {
            if (mm.find(p->random) != mm.end())
                  curr->random = mm[p->random];
            p = p->next;
            curr = curr->next;
        }
        
        return new_head;
    }
};
class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        RandomListNode *new_head, *p, *curr, *next, *random;
        map<RandomListNode*, RandomListNode*> mm;
        
        new_head = NULL;
        p = head;
        
        while (p != NULL) {
            // copy node
            if (mm.find(p) == mm.end()) {
                 next = new RandomListNode(p->label);
                 mm[p] = next;  // store
            } else {
                next = mm[p];   // get
            }
            
            if (new_head == NULL) {
                new_head = next;
            } else {
                curr->next = next;
            }
            
            // copy random
            if (p->random != NULL) {
                if (mm.find(p->random) == mm.end()) {
                    random = new RandomListNode(p->random->label);
                    mm[p->random] = random;  // store
                } else {
                    random = mm[p->random];  // get
                }
                next->random = random;
            }
            
            curr = next;
            p = p->next;
        }
        
        return new_head;
    }
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值