138. Copy List with Random Pointer

一、题目

  1、审题

  

  2、分析

    给出一个链表,链表有 next、random 指针。深度复制这张链表

二、解答

  1、思路:

    方法一、

      采用一个 Map 记录是创建的新节点并采用递归进行深度复制。

    public RandomListNode copyRandomList(RandomListNode head) {
        
        HashMap<Integer, RandomListNode> map = new HashMap<Integer, RandomListNode>();
        return copyRandomList(head, map);
    }
    
    private RandomListNode copyRandomList(RandomListNode head, HashMap<Integer, RandomListNode> map) {
        
        if(head == null)
            return null;
        int val = head.label;
        if(map.containsKey(val))
            return map.get(val);
        
        RandomListNode cloneNode = new RandomListNode(val);
        map.put(val, cloneNode);
        cloneNode.next = copyRandomList(head.next, map);
        cloneNode.random = copyRandomList(head.random, map);
        
        return cloneNode;
    }

  方法二、

    采用一个 Map 记录新建的节点,并采用两个循环进行 next、random 指针赋值。

    public RandomListNode copyRandomList2(RandomListNode head) {
        
        if(head == null)
            return null;
        
        HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
        
        // copy all nodes
        RandomListNode node = head;
        while(node != null) {
            map.put(node, new RandomListNode(node.label));
            node = node.next;
        }
        
        // asign next、random pointer
        node = head;
        while(node != null) {
            map.get(node).next = map.get(node.next);
            map.get(node).random = map.get(node.random);
            node = node.next;
        }
        
        return map.get(head);
    }

   方法三、

    不另外开辟新的 Map 空间。采用指针直接创建新链表。

    ①、在原链表中每个节点后插入一个新节点,新节点值为前一个结点的值。

    ②、为新节点赋值 random 指针。

    ③、将新节点全部抽离出来形成新链表,并恢复原来的链表结构。

    public RandomListNode copyRandomList3(RandomListNode head) {
        
        RandomListNode iter = head, next;
        
        // First round: make copy of each node, and link them together side-by-side in a single list.
        while(iter != null) {
            next = iter.next;
            RandomListNode copy = new RandomListNode(iter.label);
            iter.next = copy;
            copy.next = next;
            iter = next;
        }
        
        // Second round: assign random pointers for the copy nodes.
        iter = head;
        while(iter != null) {
            if(iter.random != null)
                iter.next.random = iter.random.next;
            iter = iter.next.next;
        }
        
        // Third round: restore the original list, and extract the copy list.
        iter = head;
        RandomListNode pseudoHead = new RandomListNode(0);
        RandomListNode copy, copyIter = pseudoHead;
        while(iter != null) {
            next = iter.next.next;
            
            copy = iter.next;
            copyIter.next = copy;
            copyIter = copy;
            
            iter.next = next;
            
            iter = next;
        }
        return pseudoHead.next;
    }
原文地址:https://www.cnblogs.com/skillking/p/9767345.html