克隆链表
一种特殊的单链表节点类描述如下:
class Node {
int value;
Node next;
Node rand;
Node(int val) {
value = val;
}
}
rand
指针是单链表节点结构中新增的指针,rand
可能指向链表中的任意一个节点,也可能指向null
。
要求:给定一个由Node
节点类型组成的无环单链表的头节点head
,请实现一个函数完成这个链表的复制,并返回复制的新链表的头节点。
package copy;
import java.util.HashMap;
public class CopyListWithRandom {
/**
* 链表复制
* <p>使用Hash表实现</p>
* <p>时间复杂度:O(n)</p>
* <p>额外空间复杂度:O(n)</p>
*
* @param root head
*
* @return 复制的链表
*/
public static Node copyListWithRand1(Node root) {
// 特殊值判断
if (root == null) {
return null;
}
// 定义Hash表,构造老节点与新节点的对应关系
HashMap<Node, Node> map = new HashMap<>();
Node old = root;
while (old != null) {
map.put(old, new Node(old.value));
old = old.next;
}
// 构造复制的节点的链表关系
old = root;
while (old != null) {
map.get(old).next = map.get(old.next);
map.get(old).rand = map.get(old.rand);
old = old.next;
}
return map.get(root);
}
/**
* 链表复制
* <p>不用Hash链表构造新老节点对应关系</p>
* <p>将新节点始终放在老节点的next来构造对应关系</p>
* <p>时间复杂度:O(n)</p>
* <p>额外空间复杂度:O(1)</p>
*
* @param root head
*
* @return 复制的链表
*/
public static Node copyListWithRand2(Node root) {
// 特殊值判断
if (root == null) {
return null;
}
// 新建新节点,构造新老节点对应关系
Node next;
Node old = root;
while (old != null) {
next = old.next;
Node node = new Node(old.value);
node.next = next;
old.next = node;
old = next;
}
// 复制老节点的rand关系
old = root;
while (old != null) {
old.next.rand = old.rand == null ? null : old.rand.next;
old = old.next.next;
}
// 分离新老链表
old = root;
Node head = old.next;
while (old != null) {
next = old.next;
old.next = next.next;
old = old.next;
next.next = old == null ? null : old.next;
}
return head;
}
public static class Node {
public int value;
public Node next;
/**
* rand指针是单链表节点结构中新增的指针
* rand可能指向链表中的任意一个节点
* 也可能指向null
*/
public Node rand;
public Node(int data) {
this.value = data;
}
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!