题目分析
- 原题目内容太长,我们简单分析下主要题意
- 有一个长度为n的链表,每个节点除了有next指针,还有一个随即指针random
- 我们需要复制这个链表,这个新链表的指针指向必须与原链表的指针指向相同
示例

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
哈希表实现
主要思路
- 遍历链表,复制每一个节点组成新链表,并将原链表节点和对应的新节点加入到Map中
- 然后再次遍历原链表,如果原链表节点随机指针不为空时
- 从Map中获取原链表节点随机指针对应的新链表节点
- 将新链表节点的随机指针指向对应的节点
代码实现
public Node copyRandomList(Node head) {
if(head == null){
return null
}
Map<Node,Node> map = new HashMap<>()
Node dummty = new Node(-1)
Node tail = dummty
Node cur = head
while(cur != null){
Node temp = new Node(cur.val)
map.put(cur,temp)
tail.next = temp
tail = tail.next
cur = cur.next
}
tail = dummty.next
while(head != null){
if(head.random != null){
tail.random = map.get(head.random)
}
tail = tail.next
head = head.next
}
return dummty.next
}
空间优化
主要思路
- 创建虚拟头结点,并指向head
- 遍历链表,并复制节点,每个节点指向复制后的节点
- 比如1 -> 2 -> 3复制后变为dummty -> 1 -> 1 -> 2 -> 2 -> 3 -> 3
- 再次遍历链表,此时head.next是复制后的新节点
- 所以 head.next.random = head.random.next
- 最后拆分链表
代码实现
public Node copyRandomList(Node head) {
if(head == null){
return null
}
Node dummty = new Node(-1)
dummty.next = head
while(head != null){
Node temp = new Node(head.val)
temp.next = head.next
head.next = temp
head = temp.next
}
head = dummty.next
while(head != null){
if(head.random != null){
head.next.random = head.random.next
}
head = head.next.next
}
head = dummty.next
Node res = head.next
while(head != null){
Node t = head.next
if(head.next != null){
head.next = head.next.next
}
head = t
}
return res
}