Sword finger Offer 35 Replication of complex linked list (java implementation, in-situ modification solution)

Posted by numtre on Sun, 09 Jan 2022 23:07:07 +0100

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.

Topics: Algorithm data structure leetcode linked list