简述Java编程实现复杂链表复制 ?
参考答案:
在Java中,复制一个复杂的链表(例如,包含随机指针的链表)可能需要一些额外的步骤。假设我们有一个链表节点类Node
,每个节点有一个next
指针指向下一个节点,还有一个random
指针可以指向链表中的任何节点。
首先,我们需要定义这个链表节点类:
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
然后,我们可以使用以下步骤来复制这个链表:
- 遍历原始链表,对于每个节点,创建其副本,并将副本插入到原始节点之后。同时,维护一个哈希表来存储原始节点和对应副本的映射关系。
- 再次遍历链表,对于每个节点,设置其副本的
random
指针。由于我们已经将副本插入到了原始节点之后,因此可以通过原始节点的next
指针找到其副本,并根据原始节点的random
指针设置副本的random
指针。 - 最后,我们再次遍历链表,将原始节点和副本节点分离,得到复制后的链表。
下面是实现这个算法的Java代码:
import java.util.HashMap;
import java.util.Map;
public class Solution {
public Node copyRandomList(Node head) {
if (head == null) {
return null;
}
// Step 1: Create copies of nodes and insert them after original nodes.
Node curr = head;
while (curr != null) {
Node copy = new Node(curr.val);
copy.next = curr.next;
curr.next = copy;
curr = copy.next;
}
// Step 2: Set random pointers of copied nodes.
curr = head;
while (curr != null) {
if (curr.random != null) {
curr.next.random = curr.random.next;
}
curr = curr.next.next;
}
// Step 3: Separate original nodes and copied nodes.
curr = head;
Node dummy = new Node(0); // Dummy node for the copied list.
Node copyCurr = dummy;
while (curr != null) {
copyCurr.next = curr.next;
curr.next = curr.next.next;
copyCurr = copyCurr.next;
curr = curr.next;
}
return dummy.next;
}
}
在这个算法中,我们使用了三次遍历。第一次遍历用于复制节点并插入到原始节点之后,第二次遍历用于设置副本的random
指针,第三次遍历用于分离原始节点和副本节点。因此,这个算法的时间复杂度是O(n),其中n是链表的长度。由于我们使用了额外的空间来存储副本节点和哈希表,因此空间复杂度是O(n)。