## Title Description

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

Tag: “sword finger offer”, “linked list”, “single linked list”

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”:

- Create a “virtual header node”
`dummy`

To reduce boundary judgment, the subsequent answer list will be connected to`dummy`

Behind; - use
`tail`

Represents the end of the currently valid linked list; - 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.

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

- 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 {
public ListNode deleteDuplication(ListNode pHead) {
ListNode dummy = new ListNode(-1);
ListNode tail = dummy;
while (pHead != null) {
//When entering the loop, make sure that the {phead} is not the same as the previous node
if (pHead.next == null || pHead.next.val != pHead.val) {
tail.next = pHead;
tail = pHead;
}
//If {phead} is the same as the next node, skip the same node (reach the last bit of "continuous same section")
while (pHead.next != null && pHead.val == pHead.next.val) pHead = pHead.next;
pHead = pHead.next;
}
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 {
public ListNode deleteDuplication(ListNode pHead) {
//Recursive exit: when the "input node is empty" or "there is no next node", it returns directly
if (pHead == null || pHead.next == null) return pHead;
if (pHead.val != pHead.next.val) {
//If the values of "current node" and "next node" are different, the current node can be retained
pHead.next = deleteDuplication(pHead.next);
return pHead;
} else {
//If the current node is the same as the next node, you need to skip a continuous segment with the same value
ListNode tmp = pHead;
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 {
public ListNode deleteDuplication(ListNode head) {
if (head == null) return head;
ListNode dummy = new ListNode(-109);
ListNode tail = dummy;
while (head != null) {
//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
if (tail.val != head.val) {
tail.next = head;
tail = tail.next;
}
head = head.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 ω ・´)