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

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 lists1->2->3->3->4->4->5After treatment1->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”dummyTo reduce boundary judgment, the subsequent answer list will be connected todummyBehind;
  2. usetailRepresents the end of the currently valid linked list;
  3. Through original inputpHeadScan 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:pHeadThere is no next node,pHeadPointer that can be retained (inserted at the end of the answer)tailBack);pHeadThere is a node, but the value is the same aspHeadinequality,pHeadCan be retained;
  • Skip: when foundpHeadIf 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:

[sword finger selection] explain in detail two solutions to

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

[sword finger selection] explain in detail two solutions to

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 usdeleteDuplicationFunctions 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 parameterspHeadIs empty, orpHead.nextIf it is empty, there must be no duplicate element and it can be returned directlypHead
  • Minimum operation of recursive link: consider how to delete logic later:
  • Obviously, whenpHead.val != pHead.next.valWhen,pHeadCan be retained, so we just need topHead.nextPass in a recursive function and take the return value aspHead.next, then returnpHeadOK;
  • WhenpHead.val == pHead.next.valWhen,pHeadCannot be reserved, we need to use temporary variablestmpSkip andpHead.valA continuous segment with the same value willtmpThe 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” seriesNo.56The 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 ω ・´)

[sword finger selection] explain in detail two solutions to