LeetCode 138: random pointer list with copy Copy List with Random Pointer

Given a list, each node contains a random additional pointer that can point to any node in the linked list node or empty.

He asked to return to the list of deep copy .

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

Example:

img

输入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}

解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。

prompt:

  1. You must return to the head of copies given as a reference to a clone of the list.

Note:

  1. You must return the copy of the given head as a reference to the cloned list.

Problem-solving ideas:

Due to the need to consider random pointer, a pointer to a random node may be null, or it may be the last node of the list, under a deep copy, you can not randomly pointer to the new node points to the original list of the list, so I can not get over the new list.

Solving two kinds of methods, one is to copy all the nodes, the temporarily stored in a data structure, and then again traversing the data structure to find a copy node, the pointer is determined randomly directed. Because each node has to find a random node pointer, if the use of hash table (dictionary) to find its complexity is O (1), so you can put down the total time complexity of O (n), all due to the temporary storage nodes , the spatial complexity is O (n).

Another solving method is the need to traverse the three results obtained, each of the first node is simply copied, and the copied node is connected to the back of the original node, and so on. After determining the relationship randomly subdivided node list. It is a very clever idea:

Original list: 1-> 2-> 3
copied back to the original node for each node: 1-> 1-> 2-> 2-> 3-> 3
Copy relationship pointers random
split list: 1-> 2- > 3, 1-> 2-> 3

When the pointer to a random replication, the original random node one node of a node is the new node randomly. After 1-> 2-> 3, is a random node 3, node replication:: If the original list 1-> 1-> 2-> 2-> 3-> 3

We simply new node (Node 1 after the original one node 1) point after a random node of the original node of a node (random node of the original node 3, and after copying after a random node node 3 is still 3, but this node is a new node), and finally splitting the list (list split does not affect the relationship between the node points). Its time complexity is O (n), the spatial complexity is O (1).

the first method:

Java:

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) return null;
        HashMap<Node, Node> map = new HashMap<>();//借助hashMap
        Node newHead = new Node(0);//虚拟头节点
        Node cur = newHead;//指针指向当前节点
        Node tmp;
        while (head != null) {
            if (map.containsKey(head)) {//查询原节点是否已存在于map
                tmp = map.get(head);//如果存在直接取value值
            } else {
                tmp = new Node(head.val);//不存在则新建一个值相同的节点
                map.put(head, tmp);//存入map,key为原节点,value为新节点
            }
            cur.next = tmp;
            if (head.random != null) {//原节点的随机节点不为空的情况下
                if (map.containsKey(head.random)) {//查询该随即节点是否已存在于map
                    tmp.random = map.get(head.random);//存在则直接将新节点的随机指针指向其value值
                } else {
                    tmp.random = new Node(head.random.val);//不存在则新建一个值相同的随机节点
                    map.put(head.random, tmp.random);//存入map,key为原节点的随机节点,value为新节点的随机节点
                }
            }
            head = head.next;//刷新原链表当前头节点
            cur = tmp;//即cur=cur.next,刷新新链表当前节点
        }
        return newHead.next;
    }
}

Python3:

class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        if not head: return None
        map = {}
        newHead = Node(val=0, next=None, random=None)
        cur = newHead
        while head:
            if head in map.keys():
                tmp = map.get(head)
            else:
                tmp = Node(val=head.val, next=None, random=None)
                map.setdefault(head, tmp)
            cur.next = tmp
            if head.random:
                if head.random in map.keys():
                    tmp.random = map.get(head.random)
                else:
                    tmp.random = Node(val=head.random.val, next=None, random=None)
                    map.setdefault(head.random, tmp.random)
            head = head.next
            cur = tmp
        return newHead.next

The second method:

Java:

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) return null;
        //复制节点 1->2->3 ==> 1->1->1->2->2->3->3
        Node cur = head;
        while (cur != null) {
            Node next = cur.next;
            Node tmp = new Node(cur.val);
            cur.next = tmp;
            tmp.next = next;
            cur = next;
        }
        //复制随机指针
        cur = head;
        while (cur != null) {
            //cur.next.random=>新节点的随机节点  cur.random.next=>原节点的随机节点的下一个节点
            cur.next.random = cur.random == null ? null : cur.random.next;
            cur = cur.next.next;//链表扩展一倍后肯定是偶数位链表,所以可以直接用cur.next.next
        }
        //分离节点
        cur = head;
        Node newHead = head.next;//新链表头节点
        while (cur != null) {
            Node tmp = cur.next;
            cur.next = tmp.next;
            cur = cur.next;
            tmp.next = cur == null ? null : cur.next;
        }
        return newHead;
    }
}

Python3:

class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        if not head: return None
        cur = head
        while cur:
            next = cur.next
            tmp = Node(val=cur.val, next=next, random=None)
            cur.next = tmp
            cur = next
        cur = head
        while cur:
            cur.next.random = cur.random.next if cur.random else None
            cur = cur.next.next
        cur = head
        newHead = head.next
        while cur:
            tmp = cur.next
            cur.next = tmp.next
            cur = cur.next
            tmp.next = cur.next if cur else None
        return newHead

Guess you like

Origin www.cnblogs.com/zhangzhe532/p/11263136.html
Recommended