复杂链表的复制

问题描述:

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


例子

示例 1:
在这里插入图片描述

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例 2:
在这里插入图片描述

输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]

示例 3:
在这里插入图片描述
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]

示例 4:
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。


提示:

提示:

  • -10000 <= Node.val <= 10000
  • Node.random 为空(null)或指向链表中的节点。
  • 节点数目不超过 1000 。

代码实现:

对于简单链表的深拷贝,按照顺序遍历一遍就可以,该题目中存在随机指针,在拷贝时,你不能确定他所指向的结点是否已经创建了。

所以可以尝试用拆分停留的方式,就是在原链表每个结点后面添加一个和原节点一样的结点,用复制结点的随机指针指向原结点的随机指针的后一个,最后再把两个链表拆开就得到了结果

1.拆分停留:

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

public Node copyRandomList(Node head) {
        if (head==null) return null;
       for (Node node=head;node!=null;node=node.next.next){// 插入每个结点的复制版
           Node nodeCopy=new Node(node.val);// 创建结点
           nodeCopy.next=node.next;// 插入
           node.next=nodeCopy;
       }
       for (Node node=head;node!=null;node=node.next.next){// 将复制的随机结点指向原节点指向的下一个结点
           node.next.random=node.random!=null?node.random.next:null;
       }
       Node rt=head.next;// 记录头结点
       for (Node node=head;node!=null;node=node.next){// 将复制链表和原链表分开
           Node nodeNew = node.next;
           node.next=node.next.next;
           nodeNew.next=node.next!=null?nodeNew.next.next:null;
       }
       return rt;
    }

运行截图

在这里插入图片描述


题目来源:力扣(LeetCode)
链接: LeetCode题目

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天将降大任于我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值