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

168 阅读2分钟

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

删除排序链表中的重复元素 Remove duplicates from sorted list

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

原题

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 Given the head of a sorted linked list, delete all duplicates such that each element appears only once. Return the linked list sorted as well.

Example:

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

Input: head = [1,1,2,3,3]
Output: [1,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.


思考线


解题思路

如果这道题是无序的链表,要考虑如何保证节点的值是不重复的还是有一定难度的,但是这道题的前提是排好序的链表,所以我们比较容易能想出解决方案。

我是这样考虑的

  1. 我们先记录下head的值设为temp

  2. 比较head的下一个值是否和temp相同

    1. 若相同则说明是重复节点,我们需要把head.next的指针指向 head.next.next
    2. 若不同,或是head.next不存在则说明不是重复节点,我们把 head指向 head.next.然后把temp指向此时head的值。
  3. 重复以上操作直到head为 null, 然后我们把新链表的头部返回过去,也就是原链表的头部

代码实现如下

/**
 * 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 {
    if (!head) return head;
    let temp = head.val; // 设置当前要比较的值。
    let list = head;
    while (list) {
        if (list.next && list.next.val === temp) {
            list.next = list.next.next;
        } else {
            list = list.next;
            temp = list?.val ?? null;
        }
    }
    return head;

};

但是我们再思考一下,我们真的需要设置这个temp变量吗?

其实在整个过程中我们只需要前一个跟后一个比较即可,也就是上面步骤2的操作。然后重复执行,直到 list.nextnull.

我们再看一下去掉temp后的结果

function deleteDuplicates(head: ListNode | null): ListNode | null {
    if (!head) return head;
    let list = head;
    while (list.next) {
        if ( list.next.val === list.val) {
            list.next = list.next.next;
        } else {
            list = list.next;
        }
    }
    return head;

};

这样写我们可以省去一个变量的书写,同时也少了很多极限情况的讨论。在解题过程中,减少极限情况的讨论可以让我们更容易解题,少犯错误,同时也让代码更简洁。我们之前解题设置的虚拟头结点dummyHead也是为了减少极限的讨论。

时间复杂度

O(n): n为链表的长度。

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