138 复杂链表的深度拷贝 copy list with random pointer

问题分析:

一个复杂的链表,节点中有一个指向本链表任意某个节点的随机指针(也可能为空),求这个链表的深度拷贝

思路:

此题有两种方法,一种是按照原链表next的顺序依次创建节点,并处理好新链表的next指针,同时把原节点与新节点的对应关系保存到一个hash_map中,然后第二次循环将random指针处理好。这种方法的时间复杂度是O(n),空间复杂度也是O(n)。

第二种方法则是在原链表的每个节点之后插入一个新的节点,这样原节点与新节点的对应关系就已经明确了,因此不需要用hash_map保存,但是需要第三次循环将整个链表拆分成两个。这种方法的时间复杂度是O(n),空间复杂度是O(1)。

但是利用hash_map的方法具有其他的优点,如果在循环中加入一个判断,就可以检测出链表中是否有循环;而第二种方法则不行,会陷入死循环。

/**
 * Definition for singly-linked list with a random pointer.
 * class RandomListNode {
 *     int label;
 *     RandomListNode next, random;
 *     RandomListNode(int x) { this.label = x; }
 * };
 */
public class Solution {
    public RandomListNode copyRandomList(RandomListNode head) {
        HashMap<RandomListNode,RandomListNode> map=new HashMap<>();
        RandomListNode cur=head;
        //第一步,将结点存入哈希表
        while(cur!=null){
            RandomListNode newNode=new RandomListNode(cur.label);
            map.put(cur,newNode);
            cur=cur.next;
        }
        //
        cur=head;
        while(cur!=null){
            RandomListNode node=map.get(cur);
            node.next=map.get(cur.next);
            node.random=map.get(cur.random);
            cur=cur.next;
        }
        return map.get(head);
    }
}

方法二:c++

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

        RandomListNode *now = head;         //复制各个节点
        while(now){
            RandomListNode *copy = new RandomListNode(now->label);
            copy->next = now->next;
            now->next = copy;
            now = copy->next;
        }

        for(now=head; now; now=now->next->next){        //复制random指针域
            now->next->random = (now->random)?now->random->next:NULL;
        }

        RandomListNode* h = head->next;     //断开成两个链表
        RandomListNode* t = h;
        RandomListNode* tail = head;
        for(;;){
            tail->next = t->next;
            tail = tail->next;
            if(tail==NULL){
                break;
            }
            t->next = tail->next;
            t = t->next;
        }
        return h;
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值