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;

    }

};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值