题目考察如何实现DeepCopy
case1:
然后可以边遍历边创建对应的复制节点,并且使用一个Map来保存原来的节点以及复制后的节点的映射关系,之后再去遍历原链表,基于原节点的next和random来构建复制节点的next域和random域
时间复杂度O(N) 空间复杂度O(N)
class Solution {
public Node copyRandomList(Node head) {
if(head==null) return head;
Map<Node,Node> map = new HashMap<>();//key:原结点 value:对应的copy节点
for(Node cur = head;cur!=null;cur=cur.next){
map.put(cur,new Node(cur.val));
}
//将拷贝后的结点串成一个链表也就是构建拷贝next与random域
for(Node cur = head;cur!=null;cur=cur.next){
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
}
return map.get(head);
}
}
case2:原地修改
思想:先拷贝原链表中的每一个结点(仅拷贝值),然后插入到复制的结点的后面比如1->2->3 复制后变为
1->1->2->2->3->3
这样我们的话复制后的结点已经有了先后顺序(next域不必再额外链接了),现在只需要先链接这些复制后的结点的random域,然后再将复制后的链表给拆分成两个链表即可
时间复杂度O(N) 空间复杂度O(1)不考虑创建复制节点所需要的空间
class Solution {
public Node copyRandomList(Node head) {
if(head==null) return null;
Node curNode = head;
//step1,在原链表中的每个结合后插入一个对应的复制节点
while(curNode!=null){
Node next = curNode.next;
Node copyNode = new Node(curNode.val);
copyNode.next = curNode.next;
curNode.next = copyNode;
curNode = next;
}
//构造copyNode的next和random域
curNode = head;
while(curNode!=null){
//防止断链
Node next = curNode.next.next;
//构造copyNode的next域
curNode.next.next = curNode.next.next;
//构造copyNode的random域
if(curNode.random!=null){
curNode.next.random = curNode.random.next;
}
curNode = next;
}
//拆分链表
curNode = head;
Node copyHead = head.next;
while(curNode!=null){
//防止断链
Node nextCurNode = curNode.next.next;
curNode.next.next = (next!=null)?next.next:null;
curNode.next = nextCurNode;
curNode = curNode.next;
}
return copyHead;
}
}