「这是我参与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
是链表的长度,因为我们需要从头走到尾。
这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。