leetcode138-复制带随机指针的链表

方法一:利用map,空间复杂度O(N)

class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        if(head==NULL)
            return NULL;
        //先进行浅拷贝
        //先设置一个哨兵节点,方便直接从头拷贝
         RandomListNode *header=new  RandomListNode(-1);
         RandomListNode *p=header;
         RandomListNode *q=head;
         map<RandomListNode*,RandomListNode*> m;
        while(q){//拷贝next指针
              RandomListNode *tmp=new RandomListNode(q->label);
              p->next=tmp;
              m[q]=tmp;
              p=p->next;
              q=q->next;
        }
        //拷贝random指针
        p=header->next;
        q=head;
        while(q){
            p->random=m[q->random];
            q=q->next;
            p=p->next;
        }
        return header->next;
    }
};

方法二:将每个节点都复制一遍,然后拷贝随机指针:副本节点的随机指针是原节点的随机指针的下一个节点;

空间复杂度为O(1)

class Solution {

public:

    RandomListNode *copyRandomList(RandomListNode *head) {

        if(head==NULL)

            return NULL;

        //先复制每一个节点,如原来是1->2->3->4,复制后变为1->1'->2->2'->3->3'->4->4'

        RandomListNode *p=head;

        while(p){

            RandomListNode *tmp=new RandomListNode(p->label);

            tmp->next=p->next;

            p->next=tmp;

            p=p->next->next;//走两步,跨过新加入的节点     

        }

        //复制Random指针

        p=head;

        RandomListNode *q=head->next;

        while(p){

            if(p->random)

            q->random=p->random->next;

            p=p->next->next;//注意,此处要走两步

            if(q->next)

            q=q->next->next;//注意,此处要走两步

        }

        //分离两个链表:即分为1->2->3->4和1'->2'->3'->4'

        p=head;

        q=head->next;

        RandomListNode *newHead=q;

        RandomListNode *tmp1=NULL;

        RandomListNode *tmp2=NULL;

         

        while(p){

            tmp1=p->next->next;

            if(q->next==NULL)

                break;//1->1'的情况在此退出(链表遍历到最后两个节点时也从此处退出)

            tmp2=q->next->next;//此处:链表至少有4个节点1->1'->2->2'

            p->next=tmp1;

            q->next=tmp2;

            p=p->next;

            q=q->next;

            tmp1=tmp1->next->next;//链表至少有4个节点1->1'->2->2',所以可以保证tmp1往后移动一次

            if(tmp2->next)

                tmp2=tmp2->next->next;

            else

                tmp2=NULL;//即tmp2已经是链表最后一个节点,此时会在下次一进入while时,从break处退出(q->next==NULL)

        }

        p->next=NULL;

        return newHead;

    }

};

 

猜你喜欢

转载自blog.csdn.net/u014450222/article/details/83002321
今日推荐