思路
-
链表操作
时间复杂度O(n),空间复杂度O(1)。 -
HashMap
使用HashMap复制结点关系
时间复杂度O(n),空间复杂度O(1)。
链表操作代码
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
if(pHead == null) return null;
RandomListNode p = pHead;
// 在原有结点之后新增复制结点
while(p != null) {
RandomListNode node = new RandomListNode(p.label);
node.next = p.next;
p.next = node;
p = p.next.next;
}
// 复制随机指针
p = pHead;
while(p != null) {
p.next.random = p.random == null ? null : p.random.next;
p = p.next.next;
}
// 摘链
RandomListNode head = pHead.next;
RandomListNode q = pHead;
p = pHead.next;
while(q != null) {
q.next = p.next;
q = q.next;
// 空指针的判断
p.next = q == null ? null : q.next;
p = p.next;
}
return head;
}
}
HashMap代码
import java.util.HashMap;
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
if(pHead == null) return null;
HashMap<RandomListNode,RandomListNode> map = new HashMap<>();
RandomListNode p = pHead;
while(p != null) {
map.put(p, new RandomListNode(p.label));
p = p.next;
}
p = pHead;
while(p != null) {
if(p.next != null) {
// 不存在Hash值情况的考虑
map.get(p).next = map.get(p.next);
} else {
map.get(p).next = null;
}
// 根据题意,指向任意一个结点,不存在null的情况
map.get(p).random = map.get(p.random);
p = p.next;
}
return map.get(pHead);
}
}
笔记
q在循环体内做了改变,在下一次循环前又被使用,需要在循环体内判断,HashMap的get索引同理。
while(q != null) {
q.next = p.next;
q = q.next;
// 空指针的判断
p.next = q == null ? null : q.next;
p = p.next;
}