# [sword finger selection] explain in detail two solutions to “delete duplicate nodes in the linked list”

Time：2022-1-2

## Title Description

This is from niuke.com“JZ 56 delete duplicate nodes in the linked list, difficulty is“More difficult”

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, linked lists`1->2->3->3->4->4->5`After treatment`1->2->5`

Example 1:

``````Input: {1,3,4,4,3}

Return value: {1,2,5}``````

requirement:

• Time: 1 s
• Space: 64 m

## iterative method

First, a more “intuitive and general” idea is to adopt the method of “traversing while constructing”:

1. Create a “virtual header node”`dummy`To reduce boundary judgment, the subsequent answer list will be connected to`dummy`Behind;
2. use`tail`Represents the end of the currently valid linked list;
3. Through original input`pHead`Scan the linked list with the pointer.

Traverse the original linked list. As long as the original linked list has not reached the end, we will repeat the following decision (keep / skip logic):

• retain:`pHead`There is no next node,`pHead`Pointer that can be retained (inserted at the end of the answer)`tail`Back);`pHead`There is a node, but the value is the same as`pHead`inequality,`pHead`Can be retained;
• Skip: when found`pHead`If the value is the same as the next node, you need to skip the “same continuous segment”.

For example, take the title as an example`[1,2,3,3,4,4,5]`For example, use a graphical way to feel it.

1. The values of current node and next node are different. The current node is reserved:

1. The values of current node and next node are the same. Skip the same continuous segment. The current node cannot be retained:

code:

``````class Solution {
ListNode dummy = new ListNode(-1);
ListNode tail = dummy;
//When entering the loop, make sure that the {phead} is not the same as the previous node
}
//If {phead} is the same as the next node, skip the same node (reach the last bit of "continuous same section")
}
tail.next = null;
return dummy.next;
}
}``````
• Time complexity:
• Space complexity:

## Recursive solution

Compared with iterative solution, recursive solution has simpler code, but higher thinking difficulty.

First of all, whether it is a “linked list” topic or not, before implementing recursion, we need to clarify “what function we expect the recursive function to complete”, that is, design our recursive function signature.

Obviously, we want to have a recursive function: the incoming chain header node, delete the duplicate elements of the incoming chain list, and return the chain header node after the operation.

This function and topic are to be realized by us`deleteDuplication`Functions are the same, so we can directly use the original function as a recursive function.

Then consider “recursive exit” and “minimum operation of recursive link”:

• Recursive exit: consider the case where we no longer need the “delete” operation. Obviously, when you pass in parameters`pHead`Is empty, or`pHead.next`If it is empty, there must be no duplicate element and it can be returned directly`pHead`
• Minimum operation of recursive link: consider how to delete logic later:
• Obviously, when`pHead.val != pHead.next.val`When,`pHead`Can be retained, so we just need to`pHead.next`Pass in a recursive function and take the return value as`pHead.next`, then return`pHead`OK;
• When`pHead.val == pHead.next.val`When,`pHead`Cannot be reserved, we need to use temporary variables`tmp`Skip and`pHead.val`A continuous segment with the same value will`tmp`The result obtained by passing in the recursive function is returned as this time.

code:

``````public class Solution {
//Recursive exit: when the "input node is empty" or "there is no next node", it returns directly

//If the values of "current node" and "next node" are different, the current node can be retained
} else {
//If the current node is the same as the next node, you need to skip a continuous segment with the same value
while (tmp != null && tmp.val == pHead.val) tmp = tmp.next;
return deleteDuplication(tmp);
}
}
}``````
• Time complexity:
• Space complexity: ignoring the additional space overhead caused by recursion, the complexity is

## expand

• If the problem becomes “keep one for the same node”, how to implement it?

The essence has not changed. Just grasp “when nodes can be retained during traversal”.

code:

``````class Solution {
ListNode dummy = new ListNode(-109);
ListNode tail = dummy;
//If the values are not equal, they are appended to ensure that only the first node of the same node will be added to the answer
tail = tail.next;
}
}
tail.next = null;
return dummy.next;
}
}``````
• Time complexity:
• Space complexity:

## last

This is the third article in our “selected sword fingers” series`No.56`The series began on July 1, 2021.

This series will cover all the classic and timeless topics in “sword finger offer”.

While providing the pursuit of “proof” & “ideas”, it also provides the most concise code.

Welcome to pay attention and make a friend ω ・´)

## IOS reverse 03: circular selection pointer (up)

IOS underlying principles + reverse article summary The main purpose of this paper is to understand the storage of global variables and constants in assembly, and how to restore if, while and other assembly code to high-level code global variable Before that, you need to understand the memory partition. This is not particularly clear. I […]