Copy List with Random Pointer

这个题目很早就被我当成“简单题”ac了,其实现在想想,还是自己水平太菜,才只能想到那种需要O(n)空间的方法,然后就自鸣得意了

看过之前有个大牛说过,“很多牛人,他们并不是能做出很难的题或者是想出很难的算法,大部分是把简单的东西,理解的很透彻,很到位”。


唉,实力不行,心态更不能膨胀。


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.

O(n²)暴力的方法肯定是不给力的


于是我想到用map来做,把每个new出来的节点都放到一个vector里,然后把每个label都存到map里面,记录下它的位置,这样当我复制random指针时,就可以通过map来找到节点所在vector中的index,相当于O(1)的时间就可以找到每个random指针所指向的内容了。

class Solution {
public:
    map<int,int> label_index;
    vector<RandomListNode*> nodes;
    RandomListNode *copyRandomList(RandomListNode *head) {
        if(head==NULL)
            return NULL;
        RandomListNode* node = head;
        while(node!=NULL){
            label_index.insert(pair<int,int>(node->label,label_index.size()));
            nodes.push_back(new RandomListNode(node->label));
            node = node->next;
        }
        for(int i=0;i<nodes.size()-1;i++){
            nodes[i]->next = nodes[i+1];
        }
        node = head;
        int k = 0;
        while(node!=NULL){
            RandomListNode* rd = node->random;
            if(rd==NULL){
                node= node->next;
                k++;
                continue;
            }
            int label = node->random->label;
            map<int,int>::iterator it = label_index.find(label);
            nodes[k]->random = nodes[it->second];
            k++;
            node = node->next;
        }
        return nodes[0];
        
    }
};


后来看到了一个很屌的方法   来源:http://zhedahht.blog.163.com/blog/static/254111742010819104710337/


即,把每个new出来的节点,都插入到原来链表中的对应的那个节点之后,如上图。

这样,其实相当于能在O(1)的时间找到自己应该指向的random指针。如图:

   

然后,再把这个链表拆开即可,即奇数位置的节点属于原来的链表,偶数位置的节点属于copy出来的链表。


屌爆的思路。


/**
 * 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) {
        if(head==NULL)
            return NULL;
        head = cross_insert(head);
        random_insert(head);
        return select(head);
    }
    RandomListNode* select(RandomListNode* &node){
        RandomListNode* head = NULL,*tail=NULL,*head2=NULL,*tail2=NULL;
        while(node!=NULL){
            if(head==NULL){
                head =tail= node;
                head2 =tail2=node->next;
                node = node->next->next;
                head->next=NULL;
                head2->next=NULL;
            }else{
                tail->next = node;
                tail2->next = node->next;
                node = node->next->next;
                tail = tail->next;
                tail->next=NULL;
                tail2 = tail2->next;
                tail2->next=NULL;
            }
        }
        node = head;
        return head2;
    }
    RandomListNode* cross_insert(RandomListNode* head){
        RandomListNode* node = head;
        while(node!=NULL){
            RandomListNode* t = node->next;
            node->next = new RandomListNode(node->label);
            node->next->next = t;
            node = t;
        }
        return head;
    }
    void random_insert(RandomListNode* head){
        RandomListNode* node = head;
        while(node!=NULL){
            RandomListNode* ran = node->random;
            if(ran!=NULL)
                node->next->random = ran->next;
            node = node->next->next;
        }
    }
};




===================================updated on 4th, Sep, 2014=====================================

class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        if(head==NULL)
            return NULL;
        RandomListNode* h=NULL,*t=NULL;
        RandomListNode* node = head;
        while(node!=NULL){
            RandomListNode* tmp = new RandomListNode(node->label);
            tmp->next = node->next;
            node->next = tmp;
            node = tmp->next;
        }
        node = head;
        while(node!=NULL){
            if(node->random!=NULL)
                node->next->random = node->random->next;
            node= node->next->next;
        }
        node = head;
        while(node!=NULL){
            if(h==NULL){
                h = node->next;
                node->next = h->next;
                h->next=NULL;
                t = h;
            }else{
                t->next = node->next;
                t = t->next;
                node->next = t->next;
                t->next=NULL;
            }
            node = node->next;
        }
        return h;
    }
};

回头看以前的代码,写的真心丑

===================================updated on 4th, Sep, 2014=====================================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值