## JZ35 replication of complex linked list

(more difficult)

### subject

describe

Enter a complex linked list (each node has a node value and two pointers, one pointing to the next node and the other special pointer random pointing to a random node). Please make a deep copy of this linked list and return the copied head node. (Note: please do not return the node reference in the parameter in the output result, otherwise the problem determination program will directly return null). The following figure is a complex linked list with 5 nodes. In the figure, the solid arrow represents the next pointer and the dotted arrow represents the random pointer. For simplicity, the pointer to null is not drawn.

Example:

Input: {1,2,3,4,5,3,5, #, 2, #}

Output: {1,2,3,4,5,3,5, #, 2, #}

Analysis: we divide the linked list into two segments. The first half {1,2,3,4,5} is a ListNode, and the second half {3,5, #, 2, #} is a random pointer field representation.

The first half of the above example can represent LISTNODES with a linked list: 1 - > 2 - > 3 - > 4 - > 5

The second half, 3, 5, #, 2, # are represented as

The position of 1 points to 3, the position of 2 points to 5, the position of 3 points to null, the position of 4 points to 2, and the position of 5 points to null

As shown below:

Example

Input:

{1,2,3,4,5,3,5,#,2,#}

Return value:

{1,2,3,4,5,3,5,#,2,#}

### thinking

I don't know why this question is divided into "more difficult" questions. Although it seems that the input of this question is the input of two linked list length and quantity elements, it actually passes a linked list during background verification (the background mechanism of this question is also tested below), and each node has a next node except the last node; There can be random nodes or no random nodes. This problem requires deep copy of the linked list, that is, all reference data types are truly copied. For this linked list, all nodes should be copied again, and a newly created header node should be used to save the subsequent results. At the same time, it is necessary to maintain the direction of the next node and random node during creation. To achieve these, you only need to traverse the linked list once, That is, the time complexity is O(n), and the following is the code implementation.

### realization

class RandomListNode { int label; RandomListNode next = null; RandomListNode random = null; RandomListNode(int label) { this.label = label; } } public class JZ35 Replication of complex linked list { public RandomListNode Clone(RandomListNode pHead) { if (pHead == null) { return null; } RandomListNode tmp = pHead; //tmp points to the first node RandomListNode head = new RandomListNode(pHead.label); //Result linked list RandomListNode cur = head; while (tmp.next != null) { cur.next = new RandomListNode(tmp.next.label); if (tmp.random != null) { cur.random = new RandomListNode(tmp.random.label); } cur = cur.next; tmp = tmp.next; } return head; } }

(here is the mechanism of the question I was curious about at that time. Is it to enter a linked list or even the direction of the random chain? I found that it is indeed to enter a linked list. Therefore, there is nothing to optimize.)

## JZ76 delete duplicate nodes in linked list

(medium)

### subject

describe

In a sorted linked list, there are duplicate nodes. Please delete the duplicate nodes in the linked list. The duplicate nodes are not retained and the chain header pointer is returned. For example, the linked list 1 - > 2 - > 3 - > 3 - > 4 - > 4 - > 5 is 1 - > 2 - > 5 after processing.

Example 1

Input:

{1,2,3,3,4,4,5}

Return value:

{1,2,5}

Example 2

Input:

{1,1,1,8}

Return value:

{8}

### thinking

When I solve this problem, I use the greedy idea. First, I create a head node of the result linked list to store the final result. The local optimization is to add a node with no duplicate value to the result linked list every time, and the global optimization is that there will be no duplicate node in the final result linked list. Although it sounds nonsense, it is indeed a greedy idea, The core problem of this idea is how to realize its local optimization in this problem. My method is to divide the one-time traversal process of the original linked list into three cases (since the first node and the last node have no predecessor and successor respectively, these two cases should be specially considered, and the situation of the intermediate node can be judged uniformly):

- The first traversal: if the value of the first node is not equal to the value of the second node, the first node should be added to the result linked list;
- The 2nd to nth-1st traversal: if the value of a node is not equal to the value of its previous node and the value of the next node, then the value of this node should be added to the result linked list;
- The nth traversal: if the value of the last node is not equal to that of the previous node, the value of this node should be added to the result linked list.

Of course, we should also consider whether the incoming parameter node is empty and whether the linked list has only one node.

### realization

public class JZ76 Delete duplicate nodes in the linked list { public ListNode deleteDuplication(ListNode pHead) { if (pHead == null || pHead.next == null) { return pHead; } ListNode cur = pHead; ListNode res = new ListNode(-1); ListNode tmp = res; ListNode pre = null; //Last result while (cur.next != null) { if ((pre == null && cur.val != cur.next.val) //First traversal || (pre != null && cur.val != pre.val && cur.val != cur.next.val) //2 ~ n-1 traversal ) { res.next = new ListNode(cur.val); res = res.next; } pre = cur; cur = cur.next; } if (cur.val != pre.val) { //Nth traversal res.next = new ListNode(cur.val); } return tmp.next; } }