剑指 offer 35 : 复杂链表的复制
哈希表
用空间换时间。
利用哈希表的查询特点,考虑构建原链表节点和新链表对应节点的键值对映射关系,在遍历构建新链表各节点的 next 和 random 引用指向即可。
/*
// 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;
}
Map<Node,Node> hashMap = new HashMap<>();
Node cur = head;
//复制各节点,并建立“原节点->新节点”的 map 映射
while(cur !=null){
hashMap.put(cur,new Node(cur.val));
cur = cur.next;
}
cur = head;
//构建新链表的next和random指向
while(cur!=null){
hashMap.get(cur).next = hashMap.get(cur.next);
hashMap.get(cur).random = hashMap.get(cur.random);
cur = cur.next;
}
//返回新链表的头结点
return hashMap.get(head);
}
}
时间复杂度
O
(
n
)
O(n)
O(n),两轮遍历链表,使用
O
(
n
)
O(n)
O(n)时间。
空间复杂度
O
(
n
)
O(n)
O(n),哈希表使用线性大小的额外空间。
拼接+拆分
在不用辅助空间的情况下实现
O
(
n
)
O(n)
O(n)的时间效率。
首先,根据原始链表的每个节点创建对应的
N
′
N'
N′,把
N
′
N'
N′链接在
N
N
N的后面。
第二步,设置复制出来的节点的
r
a
n
d
o
m
random
random。
第三步,把这个长链表拆分成两个链表。
/*
// 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 null;
}
head = copyList(head);
Node cur = head;
// while(cur != null){
// System.out.print(cur.val+"\t");
// cur = cur.next;
// }
setRandom(head);
return recconextNodes(head);
}
public Node copyList(Node head){
if(head==null){
return head;
}
Node cur = head;
while(cur != null){
Node node = new Node(cur.val);
node.next = cur.next;
cur.next = node;
cur = node.next;
}
return head;
}
public void setRandom(Node head){
if(head==null){
return;
}
Node cur = head;
while(cur !=null && cur.next != null){
if(cur.random !=null){
cur.next.random = cur.random.next;
}
cur = cur.next.next;
}
}
public Node recconextNodes(Node head){
if(head == null){
return null;
}
Node newHead = head.next;
Node cur = head;
Node newCur = newHead;
while(cur != null){
cur.next = newCur.next;
cur = cur.next;
if(cur !=null){
newCur.next = cur.next;
newCur = newCur.next;
}else{
newCur.next = null;
}
}
return newHead;
}
}
时间复杂度
O
(
n
)
O(n)
O(n)。
空间复杂度
O
(
1
)
O(1)
O(1)。