剑指Offer 35、复杂链表的复制
方法一:递归
- 使用map存储当前节点和复制节点之间的映射关系,在递归的时候,判断map中是否包含当前节点,如果不包含,就创建,然后添加到map里面;如果存在的话,直接返回。最后返回map.get(head);
- 时间复杂度:O(n),每个节点访问一遍
- 空间复杂度:O(n),哈希表的长度
Map<Node, Node> map = new HashMap<>();
public Node copyRandomList(Node head) {
if(head == null) return null;
if(!map.containsKey(head)) {
Node node = new Node(head.val);
map.put(head, node);
}else if(map.containsKey(head)) {
return map.get(head);
}
Node node = map.get(head);
node.next = copyRandomList(head.next);
node.random = copyRandomList(head.random);
return map.get(head);
}
方法二:迭代
- 遍历当前链表,在链表的每一个节点的后面添加新的复制节点,最后再把链表断开
- 时间复杂度:O(n)
- 空间复杂度:O(n),如果返回值不占空间的话,就是O(1)
public Node copyRandomList(Node head) {
if(head == null) return null;
Node temp = head;
while(temp != null) {
Node node = new Node(temp.val);
node.next = temp.next;
temp.next = node;
temp = node.next;
}
temp = head;
while(temp != null) {
if(temp.random != null) {
temp.next.random = temp.random.next;
}
temp = temp.next.next;
}
Node result = head.next;
temp = head;
Node next = result;
while(temp != null) {
temp.next = temp.next.next;
if(next.next != null) {
next.next = next.next.next;
}
next = next.next;
temp = temp.next;
}
return result;
}