方法一:用map来做是思路最简单的。
1.首先根据原链表,复制一份一模一样的链表节点存到map中。其中键为原链表的节点,值为复制后的节点。
2.根据原链表的指向关系,去构建map中复制链表节点的结构。
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
import java.util.*;
public class Solution {
public RandomListNode Clone(RandomListNode head) {
if (head == null) return null;
HashMap<RandomListNode, RandomListNode> map = new HashMap<>();
RandomListNode cur = head;
while (cur != null){
map.put(cur,new RandomListNode(cur.label));
cur = cur.next;
}
cur = head;//重新从头开始
while (cur != null){
//在map中获取原链表当前节点的下一节点的复制节点,挂到复制链表的当前节点下
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);//和上同理
cur = cur.next;
}
return map.get(head);
}
}方法二:在原链表的基础上构建映射关系。空间复杂度小。
1.先复制每个节点,创建next映射关系,然后在搭建复制节点的random映射关系;
2.将原链表与复制链表的next关系分离开来。
/*
public class Node {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public RandomListNode Clone(RandomListNode head) {
if (head == null) return null;
RandomListNode cur = head;
RandomListNode next = null;
//复制节点,并将复制后的节点挂到原节点的后面
// 1--->2
// 1--->1'--->2
while (cur != null){
next = cur.next; //先将原来的cur的下一节点保存起来
cur.next = new RandomListNode(cur.label);
cur.next.next = next;
cur = next;
}
//
cur = head;//从头开始构建映射关系(复制后节点random的指向关系)
RandomListNode curCopy = null; //表示当前节点的复制节点
while (cur != null){
next = cur.next.next;
curCopy = cur.next;
curCopy.random = cur.random != null ? cur.random.next:null;
cur = next;
}
//进行分离操作random上的指针不需要再改动了,只需要将next指针进行分离即可。
RandomListNode resHead = head.next;//保存最后需要返回的头节点(就是原头节点后的复制节点)
cur = head;
while (cur != null){
next = cur.next;//保存当前节点的下一个节点(即复制节点)
cur.next = next.next; //让复制节点的下一个节点(即原节点的下一个节点)挂在当前节点下(恢复原来的位置)
next.next = next.next != null ? next.next.next:null;//若复制节点的下一节点不为空(那么一定有下一个复制节点),将其挂在前一个复制节点后
cur = cur.next; // 后移cur
}
return resHead;
}
}
京公网安备 11010502036488号