Skip to content

35.复杂链表的复制

  • 难点在于,random结点可能还没出创建
  • 我们可以使用一个map存储结点的创建情况
  • 使用递归的思想
class Solution {
    Map<Node, Node> cachedNode = new HashMap<Node, Node>();

    public Node copyRandomList(Node head) {
		// base case
        if (head == null) {
            return null;
        }
		// map中不存在该结点,需要创建,同时会把该结点的下一个结点和random结点都创建
        if (!cachedNode.containsKey(head)) {
            Node headNew = new Node(head.val);
            cachedNode.put(head, headNew);
            headNew.next = copyRandomList(head.next);
            headNew.random = copyRandomList(head.random);
        }
		// 存在时直接返回
        return cachedNode.get(head);
    }
}
  • 另外一种思路(节省)
  • 将新旧结点串成串,如A→A′→B→B′→C→C′
  • 我们可以直接找到每一个拷贝节点 S'的随机指针应当指向的节点,即为其原节点 S 的随机指针指向的节点 T 的后继节点 T'。需要注意原节点的随机指针可能为空,我们需要特别判断这种情况
  • 然后再重新拆分链表
// class Solution {
//     Map<Node,Node> map = new HashMap<Node,Node>();
//     public Node copyRandomList(Node head) {
//         if(head == null)return null;
//         if(!map.containsKey(head)){
//             Node newhead = new Node(head.val);
//             map.put(head,newhead);
//             newhead.next = copyRandomList(head.next);
//             newhead.random = copyRandomList(head.random);
//         }
//         return map.get(head);
//     }
// }
class Solution {
    public Node copyRandomList(Node head) {
        if(head == null) return null;
        for(Node node = head; node !=null;node = node.next.next){
            Node newNode = new Node(node.val);
            newNode.next = node.next;
            node.next = newNode;
        }
        for(Node node = head; node != null;node = node.next.next){
            Node newNode = node.next;
            newNode.random = (node.random != null) ? node.random.next : null;
        }
        // 记录新链表的头结点
        Node newHead = head.next;
        for(Node node = head; node !=null;node = node.next){
            Node newNode = node.next;
            // 需要改变原链表结点的next指向,使用for循环定义中,不能使用node = node.next.next
            node.next = node.next.next;
            newNode.next = (newNode.next != null) ? newNode.next.next : null;
        }
        return newHead;
    }
}