迭代LeetCode 82. 删除排序链表中的重复元素 II

Posted 书所集录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代LeetCode 82. 删除排序链表中的重复元素 II相关的知识,希望对你有一定的参考价值。

2021 第 31 篇题解

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


题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/

题目


存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。

返回同样按升序排列的结果链表。

示例 1:

【迭代】LeetCode 82. 删除排序链表中的重复元素 II


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

示例 2:

【迭代】LeetCode 82. 删除排序链表中的重复元素 II


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

提示:

  • 链表中节点数目在范围 [0, 300]
  • -100 <= Node.val <= 100
  • 题目数据保证链表已经按升序排列

解题思路


思路:迭代

先审题,题中所给的链表已经按照升序排列,并且也给出链表头节点 ,现在要求:

  • 删除链表中所有存在数字重复情况的节点,保留原始链表中 没有重复出现 的数字。

其中返回的结果链表,仍要求是按照升序排列。

题目最后的提示中,第一条说明链表的节点数可能为 0,这个待会编码时可以考虑单独处理。

根据题意可知,链表已经按照升序排列,那么重复元素出现在链表中的位置必然是连续的。那么我们就可以通过迭代,遍历一次链表,删除重复元素。

这道题与 83. 删除排序链表中的重复元素 不同,第 83 题删除重复元素但会保留一个元素,而本题中是要将重复的元素都删除,那么这里可能会出现头节点在遍历过程中被删除。

所以我们开始将使用哑节点 ,指向链表头部。

现在说下具体的做法:

  • 因为节点可能为空,先做特殊处理,当节点为空,或者只有单节点时,返回

  • 声明哑节点 ,指向链表头节点;

  • 声明 ,初始指向

  • 声明 ,初始指向

  • 开始遍历,如果 对应的值相等时,做删除操作,具体表现为:

    • 循环删除与 对应节点值相同的节点,直到 为空节点或者其元素值不再与 的元素值相等时,然后让 指向
  • 如果 对应的值不相等时:

    • 此时不存在重复元素,那么让 指向
  • 最后,令 指向 ,继续判断;

  • 遍历结束后,返回 的下一个节点。

这里以示例 2,

【迭代】LeetCode 82. 删除排序链表中的重复元素 II


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

以上图源均来自力扣

用图示的形式查看过程:


具体实现代码如下。

# 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: ListNode) -> ListNode:
        # 空节点或单节点 直接返回 head
        if not head or not head.next:
            return head

        # 设置哑节点,减少判断,
        dummy = ListNode(0)
        dummy.next = head

        pre = dummy
        cur = head

        while cur and cur.next:
            # 存在重复节点值时,删除节点
            if cur.val == cur.next.val:
                rep = cur.val
                while cur.next and cur.next.val == rep:
                    cur.next = cur.next.next
                # 最后令 pre.next 指向 cur.next
                pre.next = cur.next
            else:
                # 不存在重复节点值时,移动 pre 指向 cur 当前指向的节点
                pre = cur
            
            # 维护 cur,继续判断
            cur = cur.next
        
        return dummy.next

复杂度分析

  • 时间复杂度: 为链表长度。
  • 空间复杂度:

欢迎关注