剑指 Offer 35. 复杂链表的复制
题目描述
请实现
copyRandomList
函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个next
指针指向下一个节点,还有一个random
指针指向链表中的任意节点或者null
。
示例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 。
思路
由于题目要求我们将链表复制一遍,而原链表有多出一个指向,这个指向具有不确定性,那么,我们可以先将原链表的next关系复制一遍,复制到一个新的链表,然后在复制的过程中,用一个Map记录原节点到新节点的一个对应关系。之后再遍历一遍原链表,将多出的指向,根据Map的映射关系,补全到新链表即可
时间复杂度:O(n)
空间复杂度:O(n)
代码
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
HashMap<Node, Node> map = new HashMap<Node, Node>();
public Node copyRandomList(Node head) {
if (head == null){
return null;
}
Node cp_head = new Node(head.val);
map.put(head, cp_head);
Node old_head = head;
Node new_head = cp_head;
while(old_head.next != null){
old_head = old_head.next;
Node p = new Node(old_head.val);
new_head.next = p;
new_head = new_head.next;
map.put(old_head, new_head);
}
old_head = head;
new_head = cp_head;
if (old_head.random != null){
Node p = map.get(old_head.random);
new_head.random = p;
}
while(old_head.next != null){
if (old_head.random != null){
Node p = map.get(old_head.random);
new_head.random = p;
}
old_head = old_head.next;
new_head = new_head.next;
}
if (old_head.random != null){
Node p = map.get(old_head.random);
new_head.random = p;
}
return cp_head;
}
}