我在面试时被问到以下问题我无法弄清楚。您将获得以下Node元素的链接列表:
class Node {
int value;
Node next; // points to next element in list
Node random; // points to one random element of list
}
假设您有这些节点的链接列表(比如20个节点),其中" next"指向下一个元素"随机"指向列表中的另一个元素(意思是,可以指向列表中的一个特定但随机选择的元素)。即,第一元素"随机"可以指向节点#5,节点第二元素的随机可以指向节点#9等
问题:如何创建一个全新的链接列表,它是此节点列表的深层副本,但保持相同的顺序和相同的链接,以便"随机"和"下一个"?
换句话说,如果使用这两个指针中的任何一个遍历这个新列表,遍历的顺序将是相同的。
一些人引用的另一个主题是通过默认克隆克隆相同的指针,但这不会解决这个挑战。
答案 0 :(得分:2)
循环所有节点并将所有节点放入HashMap
,其中Node为密钥,新节点实例为值。
Map<Node, Node> nodeMap = new HashMap<>();
...
nodeMap.put(currentNode, new Node();
现在,您再次遍历所有“旧”节点,只需循环遍历node.next
,并为每个节点复制节点,以便引用地图的值而不是旧节点本身。
Node newNode = nodeMap.get(currentNode);
newNode.value = currentNode.value;
newNode.next = nodeMap.get(currentNode.next);
newNode.random = nodeMap.get(currentNode.random);
之后你应该有一个没有重复实例的精确副本。
答案 1 :(得分:0)
在线搜索了一段时间后,我发现了这个问题的答案。很棘手。他们提出了这个主要解决方案:
见这里:http://www.programcreek.com/2012/12/leetcode-copy-list-with-random-pointer/
答案 2 :(得分:0)
答案 3 :(得分:0)
import java.util.*;
public class Solution {
HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null)
return null;
if (map.containsKey(head))
return map.get(head);
RandomListNode node = new RandomListNode(head.label);
map.put(head, node);
node.next = copyRandomList(head.next);
node.random = copyRandomList(head.random);
return node;
}
}