题解一
采用递归的思路(不知道为啥看牛客网的题解上,没找到用递归的),先不管random,采用递归的思想,就很好理解。每轮递归的时候都先创建一个新节点temp来深拷贝当前节点,temp的next指向下一轮递归返回的拷贝节点。这样整个回溯下来就创建好了一个深拷贝的链表。
还需要把random考虑进去,random应该指向某个新的节点,其实在开始回溯的时候,每个新的节点都已经new出来了,只是还没有设置好next和random。这样的话,可以在回溯的时候去设置random,只需要在每次new出新节点时,用HashMap保存旧节点和新节点的映射,这样回溯的时候就把当前节点的random设为map.get(pHead.random)就好了。
import java.util.HashMap;
public class Solution {
HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
public RandomListNode Clone(RandomListNode pHead) {
RandomListNode temp = null;
if(pHead != null) {
temp = new RandomListNode(pHead.label);
map.put(pHead, temp);
temp.next = Clone(pHead.next);
temp.random = map.get(pHead.random);
}
return temp;
}
}
题解二
直接用HashMap,先遍历一遍原来的链表,new出每个节点的拷贝节点,并把新旧节点的映射存入map中。
再次遍历原来的链表,来设置新的next和random。这时候已经可以通过map找到每个节点对应的新节点,同理新的next和新的random都很好找到(直接查找map)。
import java.util.HashMap;
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
RandomListNode temp = pHead;
RandomListNode cur = null;
while(temp != null) {
cur = new RandomListNode(temp.label);
map.put(temp, cur);
temp = temp.next;
}
temp = pHead;
while(temp != null) {
RandomListNode newNode = map.get(temp);
newNode.next = map.get(temp.next);
newNode.random = map.get(temp.random);
temp = temp.next;
}
return map.get(pHead);
}
}