LeetCode/剑指 Offer 35. 复杂链表的复制

剑指 Offer 35. 复杂链表的复制

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

示例1:

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

示例2:

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

示例3:

1
2
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]

示例4:

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

提示:

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

来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

本题解法五花八门,我在这里提供一种思路最简单的方法,就是利用HashMap。我们首先遍历一次链表,将每个结点复制一个相同的新结点并存入HashMap中,其中Key为原结点,Value为原结点的复制结点,第一遍遍历不用管每个结点的nextrandom指针。第二遍遍历链表,我们要利用每个原结点的nextrandom指针信息来完善新的复制链表,其中,新结点的next指向的就是原始结点next指向的结点对应的复制结点,即map.get(p).next = map.get(p.next);,新结点的random指向的就是原始结点的random所对应的复制结点,即map.get(p).random = map.get(p.random);最后我们返回HashMaphead对应的Value,即新的复制链表的头结点。

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
// 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 {
public Node copyRandomList(Node head) {
if (head == null)
return head;

Node p = head;
//创建HashMap用来存放原始链表和新链表的对应关系
Map<Node, Node> map = new HashMap<>();
while (p != null) {
Node temp = new Node(p.val);
//将每个原始结点拷贝一份,其中原始结点作为Key,复制结点作为Value
map.put(p, temp);
p = p.next;
}

p = head;
while (p != null) {
//新结点的next就是原结点next指向的结点的复制结点
map.get(p).next = map.get(p.next);
//新结点的random结点就是原始结点random指向的结点的复制结点
map.get(p).random = map.get(p.random);
p = p.next;
}
//返回新链表的头结点即可
return map.get(head);
}
}

Comments