复杂链表的复刻(三十六)

题目
请实现一个函数可以复制一个复杂链表。

在复杂链表中,每个结点除了有一个指针指向下一个结点外,还有一个额外的指针指向链表中的任意结点或者null。

注意:

  • 函数结束后原链表要与输入时保持一致。

算法
思想:将当前节点复制一份并且插入到当前节点的后面,然后再链接虚拟节点,最后进行拆分。不能直接返回原链表,系统会判别,最后还要将原链表恢复。
时间复杂度:O(n)
在这里插入图片描述

class Solution {
    public ListNode copyRandomList(ListNode head) {
    	//第一次遍历将每个节点复制一份插入到当前节点的后面
        for(ListNode p = head;p != null;){
            ListNode newP = new ListNode(p.val);
            ListNode next = p.next;
            p.next = newP;
            newP.next = next;
            p = next;
        }
        //为复制的节点添加随机节点
        for(ListNode p = head;p != null;p = p.next.next){
            if(p.random != null){
                p.next.random = p.random.next;
            }
        }
        
        ListNode dummy = new ListNode(-1);
        ListNode cur = dummy;
        for(ListNode p = head;p != null;p = p.next){
            cur.next = p.next;
            cur = cur.next;
            //这一步操作是为了还原链表
            p.next = p.next.next;
        }
        
        return dummy.next;
    }
}

其他做法:
用hashmap将每个节点先进行copy,然后用原节点做key,复制节点做value存进hashmap
然后遍历链表,把复制节点取出连好即可,因为hashmap的增删改查是O(n)。所以时间复杂度很低。

class Solution {
    public ListNode copyRandomList(ListNode head) {
        if(head==null)
            return null;

        Map<ListNode,ListNode> copy = new HashMap<>();

        ListNode node = head;
        while(node!=null){
            ListNode CloneNode = new ListNode(node.val);
            copy.put(node,CloneNode);
            node = node.next;
        }

        node = head;
        ListNode CloneHead = copy.get(node);
        ListNode CloneNode = CloneHead;

        while(node!=null){
            CloneNode.next = copy.get(node.next);
            if(node.random!=null){
                CloneNode.random = copy.get(node.random);
            }
            CloneNode = CloneNode.next;
            node = node.next;
        }

        return CloneHead;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值