剑指offer 面试题35.复杂链表的复制

时间O(N),空间O(N)

/*
struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x), next(NULL), random(NULL) {
    }
};
*/
class Solution {
public:
    RandomListNode* Clone(RandomListNode* pHead)
    {
        unordered_map<RandomListNode*,RandomListNode*> mp;
        return func(mp,pHead);
    }
    
    RandomListNode* func(unordered_map<RandomListNode*,RandomListNode*>& mp,RandomListNode* origin){//origin为原指针,返回该指针的深拷贝
        if(origin==nullptr){return nullptr;}
        if(mp.count(origin)){
            return mp[origin];
        }
        auto cur=new RandomListNode(origin->label);
        mp[origin]=cur;
        cur->next=func(mp,origin->next);
        cur->random=func(mp,origin->random);
        return cur;
    }
};

第二种方法是剑指offer书上的方法,蛮有意思。但牛客的AC系统是真TM傻逼,原链表后链着新链表,返回时会把新链表一起delete掉。

class Solution {
public:
    RandomListNode* Clone(RandomListNode* pHead)
    {
        if(pHead==nullptr){return nullptr;}
        auto p=pHead;
        while(p){//先建立原链表每个位置的拷贝,分别链在它的拷贝源后面,即1->1'->2->2'->3->3'->......
            auto p_next=p->next;
            auto new_p=new RandomListNode(p->label);
            p->next=new_p;
            new_p->next=p_next;
            p=p_next;
        }
        p=pHead;
        while(p){//每个新链表项的random替换为新链表项
            auto p_next=p->next->next;
            auto new_p=p->next;
            new_p->random=p->random!=nullptr?p->random->next:nullptr;
            p=p_next;            
        }
        auto new_head=pHead->next;
        pHead->next=nullptr;//SB题目 cnm,原链表头后面链着新链表AC不了,看来是系统会把原链表全部delete再判断
        p=new_head;
        while(p){
            p->next=p->next?p->next->next:nullptr;
            p=p->next;
        }
        return new_head;
    }
};

你可能感兴趣的:(剑指offer)