剑指offer T35 复制带随机指针的链表(考察深拷贝的实现)

题目考察如何实现DeepCopy
case1:
然后可以边遍历边创建对应的复制节点,并且使用一个Map来保存原来的节点以及复制后的节点的映射关系,之后再去遍历原链表,基于原节点的next和random来构建复制节点的next域和random域

时间复杂度O(N) 空间复杂度O(N)

class Solution {

    public Node copyRandomList(Node head) {
      if(head==null) return head;
      Map<Node,Node> map = new HashMap<>();//key:原结点 value:对应的copy节点
      for(Node cur = head;cur!=null;cur=cur.next){
          map.put(cur,new Node(cur.val));
      }
      //将拷贝后的结点串成一个链表也就是构建拷贝next与random域
       for(Node cur = head;cur!=null;cur=cur.next){
          map.get(cur).next = map.get(cur.next);
          map.get(cur).random = map.get(cur.random);
      }
      return map.get(head);
    }
}

case2:原地修改
思想
:先拷贝原链表中的每一个结点(仅拷贝值),然后插入到复制的结点的后面比如1->2->3 复制后变为
1->1->2->2->3->3
这样我们的话复制后的结点已经有了先后顺序(next域不必再额外链接了),现在只需要先链接这些复制后的结点的random域,然后再将复制后的链表给拆分成两个链表即可
时间复杂度O(N) 空间复杂度O(1)不考虑创建复制节点所需要的空间

class Solution {
    public Node copyRandomList(Node head) {
       if(head==null) return null;
       Node curNode = head;
       //step1,在原链表中的每个结合后插入一个对应的复制节点
       while(curNode!=null){
        Node next = curNode.next;   
        Node copyNode = new Node(curNode.val);
        copyNode.next = curNode.next;
        curNode.next = copyNode;
        curNode = next;
       }
       //构造copyNode的next和random域
       curNode = head;
       while(curNode!=null){
        //防止断链   
        Node next = curNode.next.next;  
        //构造copyNode的next域
        curNode.next.next = curNode.next.next;
        //构造copyNode的random域
        if(curNode.random!=null){
           curNode.next.random = curNode.random.next; 
        }
        curNode = next;
       }
       //拆分链表
       curNode = head;
       Node copyHead = head.next;
       while(curNode!=null){
        //防止断链   
        Node nextCurNode = curNode.next.next;
        curNode.next.next = (next!=null)?next.next:null;
        curNode.next = nextCurNode;
        curNode = curNode.next;
       }
       return copyHead;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值