如何创建维护相同订单的链接列表的深层副本

时间:2017-07-14 01:16:02

标签: java data-structures linked-list singly-linked-list

我在面试时被问到以下问题我无法弄清楚。您将获得以下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等

问题:如何创建一个全新的链接列表,它是此节点列表的深层副本,但保持相同的顺序和相同的链接,以便"随机"和"下一个"?

换句话说,如果使用这两个指针中的任何一个遍历这个新列表,遍历的顺序将是相同的。

一些人引用的另一个主题是通过默认克隆克隆相同的指针,但这不会解决这个挑战。

4 个答案:

答案 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)

另外,请查看这些链接以获取更多解决方案:

Method 1

Method 2

Method 3

参考:geeksforgeeks

答案 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;
    }
}