LeetCode 138: copy linked list with random pointer
https://leetcode-cn.com/probl...
1, Title Description
Give you a linked list with a length of n. each node contains an additional random pointer random, which can point to any node or empty node in the linked list.
Construct a deep copy of this linked list. The deep copy should consist of exactly n new nodes, in which the value of each new node is set to the value of its corresponding original node. The next pointer and random pointer of the new node should also point to the new node in the replication linked list, and these pointers in the original linked list and the replication linked list can represent the same linked list state. The pointer in the copy linked list should not point to the node in the original linked list.
For example, if there are two nodes X and Y in the original linked list, where x.random -- > y. Then, the corresponding two nodes X and Y in the copy linked list also have x.random -- > y.
Returns the header node of the copy linked list.
A linked list composed of n nodes is used to represent the linked list in input / output. Each node is represented by a [val, random_index]:
Val: one represents node Integer of val.
random_index: the node index pointed to by the random pointer (ranging from 0 to n-1); if it does not point to any node, it is null.
Your code only accepts the head node of the original linked list as the incoming parameter.
Node definition:
class Node { int val; Node next; Node random; public Node(int val) { this.val = val; this.next = null; this.random = null; } }
2, Example
Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]
3, Train of thought
Additional space complexity O(1)
1. After each node in the original linked list, copy a new node and connect it to the old node
Namely:
Before copying: 1 - > 2 - > 3,
After copying: 1 - > 1 \ ` - > 2 - > 2 \ ` - > 3 - > 3\`
2. Copy the relationship between the original node and the random pointer in the new node
3. Separating old and new nodes
Additional space complexity O(N)
1. Use Map to store new and old nodes. Key: old node, Value: new node
2. Construct a new node corresponding to the old node
3. Adjust the next pointer of the new node and the random pointer of the new node
4, Source code
Additional space complexity O(1)
/** * @author Java And algorithm learning: Monday */ public Node copyRandomList(Node head) { if (head == null) { return null; } // 1. Insert the new node behind the old node //Before adjustment: 1 - > 2 - > 3 - > null; after adjustment: 1 - > 1 ` - > 2 - > 2 ` - > 3 - > 3 ` - > null Node current = head; Node next = null; while (current != null) { //Mark the next node of the current node in the original linked list next = current.next; //Insert a new node after the current node of the original linked list current.next = new Node(current.val); //Adjust the next node of the newly inserted node current.next.next = next; //Move current node backward current = next; } // 2. Adjust the random pointer of the newly inserted node Node copy = null; current = head; while (current != null) { //New node copy = current.next; //Mark the next node of the current node in the original linked list next = current.next.next; //Adjust the new node's random node copy.random = current.random != null ? current.random.next : null; //Move current node backward current = next; } // 3. Separating old and new nodes current = head; //Record the header node of the new linked list Node res = head.next; while (current != null) { //New node copy = current.next; //Mark the next node of the current node in the original linked list next = current.next.next; //The next node of the current node points to the next node of the current node in the original linked list (that is, adjust the reference of the old node back) current.next = next; //The next node of the new node points to the next node of the current node in the original linked list (that is, extract the reference of the new node) copy.next = next != null ? next.next : null; //Move current node backward current = next; } //Returns the header node of the new linked list return res; }
Additional space complexity O(N)
/** * @author Java And algorithm learning: Monday */ public Node copyRandomListByMap(Node head) { // Key: old node, Value: new node HashMap<Node, Node> map = new HashMap<>(); Node current = head; while (current != null) { //Construct a new node corresponding to the old node map.put(current, new Node(current.val)); current = current.next; } current = head; while (current != null) { //Adjust the next pointer of the new node map.get(current).next = map.get(current.next); //Adjust the random pointer of the new node map.get(current).random = map.get(current.random); current = current.next; } return map.get(head); }
5, Test results
Additional space complexity O(1)
Additional space complexity O(N)
It can be seen from the official test results of LeetCode that there is no difference in execution time, and the difference in memory consumption (i.e. additional space complexity) is obvious. One beat 99.94% of users and the other beat only 48.64% of users.