链表的复制
链表的复制实现是指创建一个新的链表,该链表的每个结点都是原链表中对应结点的副本。
常见的实现方法有两种:
- 暴力法:对于每个结点,创建一个新结点,并将新结点的值设置为原结点的值,最后连接所有新结点。
- Hash 表法:在第一遍遍历原链表时,创建新结点并将其与原结点的地址一一对应,存储在一个 Hash 表中。在第二遍遍历原链表时,根据 Hash 表连接新结点的 next 指针。
这两种方法的时间复杂度均为 O(n),其中 n 为链表中结点的个数。
1、暴力法
class Node {
int val;
Node next;
public Node(int val) {
this.val = val;
this.next = null;
}
}
public class Solution {
public Node copyList(Node head) {
if (head == null) return null;
Node dummy = new Node(-1);
Node curr = dummy;
Node node = head;
while (node != null) {
curr.next = new Node(node.val);
curr = curr.next;
node = node.next;
}
return dummy.next;
}
}
在这段代码中,我们创建了一个虚拟头结点 dummy
,然后创建一个新结点并将其与原结点的值一一对应。最后,返回新链表的头结点。
2、Hash表法
下面是一个使用 Hash 表法实现链表复制的 Java 代码:
class Node {
int val;
Node next;
public Node(int val) {
this.val = val;
this.next = null;
}
}
public class Solution {
public Node copyList(Node head) {
if (head == null) return null;
HashMap<Node, Node> map = new HashMap<>();
Node node = head;
while (node != null) {
map.put(node, new Node(node.val));
node = node.next;
}
node = head;
while (node != null) {
map.get(node).next = map.get(node.next);
node = node.next;
}
return map.get(head);
}
}
在这段代码中,我们第一遍遍历原链表时,将新结点与原结点的地址一一对应,存储在 Hash 表中。第二遍遍历原链表时,根据 Hash 表连接新结点的 next 指针。最后,返回新链表的头结点。