问题描述:
请实现 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题目