深度拷贝带随机指针的链表(Copy List with Random Pointer)

深度拷贝带随机指针的链表(Copy List with Random Pointer)

创建一个新对象,然后将当前对象的非静态字段复制到该新对象,无论该字段是值类型的还是引用类型,都复制独立的一份。当你修改其中一个对象的任何内容时,都不会影响另一个对象的内容,这是对java类深拷贝的描述。实际上就是把一个对象完完整整的复制出来,避免在操作数据时影响到原先的对象,和浅拷贝的不同是,浅拷贝把两个对象指向了同一个地址,而深拷贝是把原先的对象完完整整的复制重新开辟了一个空间,所以使用深拷贝的一个目的就是不想影响原先的数据,所以拷贝一个新的数据体,从本质上讲他就是两个内存空间(原先的对象和现在的对象)

problem:

  •  A linked list is given such that each other node  contains an additional node random pointer which  could point to any node in the list or null, as a result, you should return a deep copy of  the list.
  • tip: first of all an idea that make a hashmap to save relation of each node stand out from my mind, which definitely  is a  solution ,it was not decent though.can you visualize what its space complexity is.

 version first

    public static Node copyRandomList(Node head) {
        Map<Node, Node> map = new HashMap<Node, Node>();
        Node newHead=head;
        while (newHead!=null){
            if (!map.containsKey(newHead)){
                Node node=new Node(newHead.val);
                map.put(newHead,node);
            }
            if (newHead.random!=null){
                Node random=newHead.random;
                if (!map.containsKey(random)){
                    Node copyRandom=new Node(random.val);
                    map.put(random,copyRandom);
                }
                map.get(newHead).random=map.get(random);
            }
            newHead=newHead.next;
        }
        // newHead was empty after loop above, that was why i assign it again
        newHead=head;
        while (newHead!=null){
            // original next Node
            Node next = newHead.next;
            // to assign copyVersionNode.next
            map.get(newHead).next=map.get(next);
            newHead=newHead.next;
        }
        return map.get(head);
    }

 

to analyze the above codes

certainly! the space complexity is o(n).the space of hashmap is increasing with list is increasing! To imagine what  hashmap duty is?there is nothing duty except using certain data structure to conserve relation in each node,can we use some other method to replace hashmap for relieving the space complexity? that is to insert a new node between each node

version second

  public static Node copyRandomList(Node head) {
        copy(head);
        copyRandom(head);
        return spilt(head);
    }

    public static void print(Node listNode) {
        if (listNode != null) {
            System.out.println(listNode.val);
            print(listNode.next);
        }
    }
    // actually, we can name the code insertAndCopy,because each code will be put a node that copy from itself,which is to replace what hashMap do
    private static void copy(Node head) {
        Node node = head;
        while (node != null) {
            Node copyCode = new Node(node.val);
            copyCode.next = node.next;
            node.next = copyCode;
            node = copyCode.next;
        }
    }


    private static Node spilt(Node head) {
        Node result = head.next;
        Node move = head.next;
        while (head != null && head.next != null) {
            // each node to point initial node
            head.next = head.next.next;
            head = head.next;
            if (move != null && move.next != null) {
                // each  duplicate node to  point next duplicate node
                move.next = move.next.next;
                move = move.next;
            }
        }
        return result;
    }

    private static void copyRandom(Node head) {
        Node node = head;
        while (node != null && node.next != null) {
            if (node.random != null) {
                // original node's  duplicate equal   duplicate of random of original node
                node.next.random = node.random.next;
            }
            // node.next equal its duplicate so  node.next.next equal its.next
            node = node.next.next;
        }
    }

Test

public static void main(String[] args) {
        /*Node node = copyRandomList2(generateDate());*/
        Node node = copyRandomList(generateDate());
        print(node);
    }
    /**
     * generate data
     *
     * @return
     */
    public static Node generateDate() {
        Node listNode = new Node(1);
        Node listNode1 = new Node(2);
        Node listNode2 = new Node(3);
        Node listNode3 = new Node(4);
        Node listNode4 = new Node(5);
        listNode.next = listNode1;
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        listNode3.next = listNode4;
        listNode3.random = listNode2;
        return listNode;
    }

 

/**
 * @author : lizi
 * @date : 2021-03-14 06:02
 **/
public class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}

 

sum up

the key point is to add an additional node between each node, which can be really efficient to raise performance of arithmetic and  pull open distance form other people

 

posted @ 2021-03-30 12:40  UpGx  阅读(111)  评论(0编辑  收藏  举报