[路飞]_每天刷leetcode_52(删除排序链表中的重复元素II Remove duplicates from sorted list II)

89 阅读2分钟

「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战

删除排序链表中的重复元素 II Remove Duplicates From Sorted List II

LeetCode传送门82. 删除排序链表中的重复元素 II

题目

给定一个已排序的链表的头 head删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表

Given the head of a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Return the linked list sorted as well.

Example:

Input: head = [1,2,3,3,4,4,5]
Output: [1,2,5]

Input: head = [1,1,1,2,3]
Output: [2,3]

Constraints:

  • The number of nodes in the list is in the range [0, 300].
  • -100 <= Node.val <= 100
  • The list is guaranteed to be sorted in ascending order.

思考线


解题思路

这道题和我们上一篇文章删除排序链表中的重复元素 很相似。只是这个题目中我们只保留不重复的元素。 我们该如何去做呢? 首先我想到的第一点问题是,如果头结点重复的话,我们有可能删除头结点。所以我们首先要做一个虚拟头结点dummyHead 来排除头结点被改变的情况。 其次是我们如何比较和删除相同元素的节点呢?我们可以比较list节点的下一个节点和下下一个节点是否相同

  • 若相同则表明遇到了相同节点,然后我们可以像删除排序链表中的重复元素一样去 把重复的元素都通过 list.next.next = list.next.next.next去清除掉。最后剩下的这个list.next = list.next.next这样就把头部保留的那一个也清除掉了。
  • 若不相同,则表明我们可以让list链表向前进一步,因为这里没有需要删除的操作。 最后 我们再把 dommyHead.next返回就好了。

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */

function deleteDuplicates(head: ListNode | null): ListNode | null {
    // 若 不相同,则,list = list.next; 
    // 循环上面的操作,直到 list.next为 null
    const dommyHead = new ListNode(-999); // 设置一个虚拟头
    dommyHead.next = head;
    let list = dommyHead;
    while (list.next?.next) { // 若后面至少有两个元素才有可比性
          // 每次检查list头结点的下一个和下下一个是否相同,若相同再检查下一个和下下下一个,直到检查为不相等
        if (list.next.val === list.next.next.val) {
            while (list.next.val === list.next.next?.val) {
                list.next.next = list.next.next.next;
            }
            // 把不相等的赋值给 list.next
            list.next = list.next.next;
        } else {
          // 说明list.next和下一个节点不相同,我们让链表往前进一步
            list = list.next;
        }
    }
    return dommyHead.next;
};

时间复杂度

O(n): 其中n是链表的长度,因为我们需要从头走到尾。

这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。