LeetCode 删除链表中的重复元素

删除单向链表的节点,需要记录前驱节点。链表的操作就是改变指针的指向。
第一种情况,删除所有的重复元素,使得最终每个元素只出现一次。比如输入:1->1->2,输出:1->2。因为需要比较相邻节点,而且需要保留一个重复的节点,所以用两个指针即可,一个指针记录前驱节点,一个指针记录下一个节点。
在这里插入图片描述

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        pre = head  #前驱节点
        while pre:
            fast = pre.next  #下一个节点
            if fast:
                if pre.val == fast.val:  #出现重复元素
                    while fast:  #从fast节点开始,向后找到第一个不同元素
                        if fast.val != pre.val:
                            break
                        fast = fast.next
                    pre.next = fast  #前驱节点pre直接指向当前fast,删除中间所有重复的元素,只留下一个,即pre所指向的节点
                else:
                    pre = pre.next
            else:   #fast为空,说明已经到了尾节点
                return head
        return head

第二种情况:删除所有重复数字的节点,只保留没有重复出现的节点。比如输入:1->1->1->2->3,输出:2->3。
这时候用两个指针就不行了,需要用到三个指针,一个同样是记录前驱节点的pre指针,一个是慢指针slow=pre.next,一个是快指针fast=pre.next.next。其中,慢指针指向第一个重复元素,而pre指针,则指向的是第一个不重复的元素,这里就不同于第一章情况,第一种情况因为需要保留一个重复节点,所以重复元素就从pre指针开始,但是第二种情况,对于重复的节点一个都不保留,那么前驱指针pre就得指向第一个不重复得元素,这样的话,利用快指针fast找到最后一个重复元素时,pre指针直接指向最后一个重复元素的next元素,就删除了中间所有的重复元素,没有保留一个。整个过程和第一种情况很相似,代码也极其相似,只是多了一个哨兵节点和指针。其中哨兵节点不存储数据,只是用来简化编码难度,主要是应对头节点出现重复元素的情况,比如上面那个例子。
在这里插入图片描述

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        fake = ListNode(None)  #利用哨兵节点简化编码难度
        fake.next = head       #因为如果当头节点元素重复时,不用哨兵节点的话,则需要对头节点特殊处理
        pre = fake
        while pre.next:
            slow = pre.next   #慢指针
            fast = slow.next   #快指针
            if fast:
                if slow.val == fast.val:
                    while fast:
                        if fast.val != slow.val:
                            break
                        fast = fast.next
                    pre.next = fast
                else:
                    pre = pre.next
            else:
                return fake.next
        return fake.next
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Rust 是一种现代的编程语言,特别适合处理内存安全和线程安全的代码。在 LeetCode 链表是经常出现的题目练习类型,Rust 语言也是一种非常适合处理链表的语言。接下来,本文将从 Rust 语言的特点、链表的定义和操作,以及 Rust 在 LeetCode 链表题目的练习等几个方面进行介绍和讲解。 Rust 语言的特点: Rust 是一种现代化的高性能、系统级、功能强大的编程语言,旨在提高软件的可靠性和安全性。Rust 语言具有如下几个特点: 1. 内存安全性:Rust 语言支持内存安全性和原语级的并发,可以有效地预防内存泄漏,空悬指针以及数据竞争等问题,保证程序的稳定性和可靠性。 2. 高性能:Rust 语言采用了“零成本抽象化”的设计思想,具有 C/C++ 等传统高性能语言的速度和效率。 3. 静态类型检查:Rust 语言支持静态类型检查,可以在编译时检查类型错误,避免一些运行时错误。 链表的定义和操作: 链表是一种数据结构,由一个个节点组成,每个节点保存着数据,并指向下一个节点。链表的定义和操作如下: 1. 定义:链表是由节点组成的数据结构,每个节点包含一个数据元素和一个指向下一个节点的指针。 2. 操作:链表的常用操作包括插入、删除、查找等,其,插入操作主要包括在链表首尾插入节点和在指定位置插入节点等,删除操作主要包括删除链表首尾节点和删除指定位置节点等,查找操作主要包括根据数据元素查找节点和根据指针查找节点等。 Rust 在 LeetCode 链表题目的练习: 在 LeetCode 链表是常见的题目类型,而 Rust 语言也是一个非常适合练习链表题目的语言。在 Rust ,我们可以定义结构体表示链表的节点,使用指针表示节点的指向关系,然后实现各种操作函数来处理链表操作。 例如,针对 LeetCode 链表题目,我们可以用 Rust 语言来编写解法,例如,反转链表,合并两个有序链表删除链表重复元素等等,这样可以更好地熟悉 Rust 语言的使用和链表的操作,提高算法和编程能力。 总之,在 Rust 处理链表是非常方便和高效的,而 LeetCode 的练习也是一个非常好的机会,让我们更好地掌握 Rust 语言和链表数据结构的知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值