Let's start with:
Please implement the copyRandomList function to copy a complex linked list. In a complex linked list, each node has a next pointer to the next node and a random pointer to any node or null in the linked list.
Example 1:
Input: head = [[7, null], [13, 0], [11, 4], [10, 2], [1, 0]]
Output: [7, null], [13, 0], [11, 4], [10, 2], [1, 0]]
Example 2:
Input: head = [[1, 1], [2, 1]]
Output: [[1, 1], [2, 1]]
reflection:
By observing the problem, we will find that there are two solutions to this problem:
1. Hash table (not recommended)
This is very simple to use. Each node of the original linked list is regarded as a key through the key value pair in the HashMap, and the new node copied through the original node is regarded as the corresponding value of each key. After all copies are made, the copied nodes (i.e. values) are connected in series through circulation using the method in the Map set, Finally, the corresponding value of the original chain header node is the header node of the new chain list.
The specific codes are as follows:
//Hash table solution public class Solution { public Node copyRandomList(Node head) { //Empty first if(head == null){ return null; } //Create a HashMap Map<Node,Node> map = new HashMap<>(); for(Node cur = head; cur != null; cur = cur.next){ //Copy a copy of the original node into the collection (at this time, only the val value is the same) map.put(cur,new Node(cur.val)); } for(Node cur = head; cur != null;cur = cur.next){ //Connect all copied nodes together with the next value map.get(cur).next = map.get(cur.next); //Copy the value of random in the original node map.get(cur).random = map.get(cur.random); } //Returns the head node of the new linked list corresponding to the original node as the key return map.get(head); } }
Test on LeetCode:
The second solution is to modify the solution in place (recommended)
Compared with hash table, I think this solution can better reflect our code ability, so I also recommend this method.
Principle:
In situ modification method is to copy each node of the original linked list and put it behind each original node, and then divide the linked list composed of the original node and the new node into two linked lists with the original node and the new node respectively. The linked list composed of the new node is the copied linked list.
General structure:
Detailed steps:
1. First judge whether it is an empty linked list.
2. Loop, copy all nodes and connect them to the back of the original node.
3. Loop. Copy the random value of the original node to the random of the new node. Note that the random of the new node can only point to the node of the new linked list, that is, the new node corresponding to the original node.
4. It is still a loop, which separates the whole linked list and connects the new nodes together to form a new linked list; The original nodes are connected together to restore the original linked list.
(pay attention to judge whether it is a tail node during segmentation)
Specific code:
class Solution { public Node copyRandomList(Node head) { //Empty linked list first if (head == null) { return null; } //Instead of using head directly, back up a cur Node cur = head; //Traversal linked list while (cur != null) { //Create a new node so that its val value is equal to the val value of the original node Node node = new Node(cur.val); //Connect the new node behind the original node node.next = cur.next; cur.next = node; //Process next original node cur = cur.next.next; } //Reset cur cur = head; //ergodic while (cur != null) { //Judge whether the random of the original node is null //No, deal with it //Since the random value of the newly created node is null by default, it doesn't matter if (cur.random != null) { //If not, copy the random point of the original node to the random of the new node //Note here: //cur.random is the value of the original node, and the new node cannot directly point to //Therefore, it can only point to the copy node of the original node //In the above, we have placed each copy node behind each original node cur.next.random = cur.random.next; } //Process next cur = cur.next.next; } //The header node where the new linked list is stored Node copyHead = head.next; cur = head; //Copy a copy for loop traversal Node copyCur = head.next; while (cur != null) { //Connect the original linked list cur.next = cur.next.next; cur = cur.next; //Judge whether it is a tail node if (copyCur.next != null) { //No, continue to connect the new linked list copyCur.next = copyCur.next.next; copyCur = copyCur.next; } } //Returns the header node of the new linked list return copyHead; } }
Test on LeetCode:
Summary:
There are two methods: hash table and in-situ modification method. No one is necessarily good or bad, but in general, in-situ modification method is recommended in the interview.