leetcode82. 删除排序链表中的重复元素 II

简介: leetcode82. 删除排序链表中的重复元素 II

题目

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

示例 1:

输入:head = [1,2,3,3,4,4,5]

输出:[1,2,5]

示例 2:

输入:head = [1,1,1,2,3]

输出:[2,3]

提示:

链表中节点数目在范围 [0, 300] 内

-100 <= Node.val <= 100

题目数据保证链表已经按升序 排列

思路1

遍历两次,第一次遍历的时候声明一个set集合,存储所有出现过多次的节点,在第二次遍历的时候使用双指针,cur指针在前,pre指针在后,如果发现cur指向的节点在集合中,则将cur向后移动,否则移动pre和cur节点

最终返回事先声明的dom节点,因为head节点指向的值可能多次出现,这里我们不可以直接返回head

复杂度

时间复杂度:

遍历了两次, O ( 2 n ) O(2n)O(2n)

空间复杂度:

存储了出现两次的节点, O ( n ) O(n)O(n)

Code2

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
        s = set()
        if not head: return head
        pre,cur = ListNode(),head
        dom = pre
        while  cur.next:
            if cur.val == cur.next.val:
                s.add(cur.val)
            cur = cur.next
        cur = head
        while cur:
            while cur and cur.val in s:    
                cur = cur.next
            
            pre.next = cur
            
            if not cur: break
            cur = cur.next
            pre = pre.next
        return dom.next

思路2

只声明一个指针cur,在while循环中判断cur.next和cur.next,next是否存在。如果这两个值不等,说明cur.next是不重复出现的,可以当作cur的下一个节点;

否则说明这两个数一样,则这两个数需要去除,我们这里进一个while循环,不断推进cur.next的值,知道cur.next的值得不是最开始出现的那两个相同的数,如果他是none,则此时cur.next就是none,不需要额外操作,如果他是一个数字,且后面还有节点,则继续循环

复杂度2

时间复杂度:

遍历一次: O ( n ) O(n)O(n)

空间复杂度:

没有声明额外空间: O ( 1 ) O(1)O(1)

Code2

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
        cur = dumy = ListNode(next=head)
        while cur.next and cur.next.next:
            val = cur.next.val
            if val == cur.next.next.val:
                while cur.next and cur.next.val == val:
                    cur.next = cur.next.next
            else:
                cur = cur.next
        return dumy.next


目录
相关文章
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
151 1
|
5月前
|
存储
203. 移除链表元素,707.设计链表,206. 反转链表
链表是数据结构中的重要概念,包含单链表、双链表和循环链表。单链表每个节点存储数据与下一节点指针;双链表增加上一节点指针;循环链表首尾相连。 **例题解析:** 1. **203. 移除链表元素**:通过遍历链表删除指定值节点,注意处理头节点特殊情况。 2. **707. 设计链表**:实现链表的增删查操作,需理解指针操作逻辑,避免直接修改目标节点。 3. **206. 反转链表**:采用双指针或递归方法改变节点指向,完成链表反转。 以上题目涵盖链表核心操作,掌握后可灵活应对相关问题。
|
7月前
|
算法 Go
【LeetCode 热题100】23:合并 K 个升序链表(详细解析)(Go语言版)
本文详细解析了 LeetCode 热题 23——合并 K 个升序链表的两种解法:优先队列(最小堆)和分治合并。题目要求将多个已排序链表合并为一个升序链表。最小堆方法通过维护节点优先级快速选择最小值,;分治合并则采用归并思想两两合并链表。文章提供了 Go 语言实现代码,并对比分析两种方法的适用场景,帮助读者深入理解链表操作与算法设计。
238 10
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
111 0
Leetcode第三十三题(搜索旋转排序数组)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
156 0
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
153 0
|
索引
力扣(LeetCode)数据结构练习题(3)------链表
力扣(LeetCode)数据结构练习题(3)------链表
253 0
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
|
存储 SQL 算法
LeetCode 题目 86:分隔链表
LeetCode 题目 86:分隔链表
|
存储 算法 Java
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
150 2