算法第四十一天-排除排序链表中的重复元素Ⅱ

这篇具有很好参考价值的文章主要介绍了算法第四十一天-排除排序链表中的重复元素Ⅱ。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

排除排序链表中的重复元素Ⅱ

题目要求

算法第四十一天-排除排序链表中的重复元素Ⅱ,算法基础,算法,python,leetcode,数据结构

解题思路

题意:在一个有序链表中,如果一个节点的值出现不止一次,那么把这个节点删除掉
重点:有序链表,所以,一个节点的值出现不止一次,那么他们必相邻。

方法一:递归

链表和树的问题,一般都可以有递归和迭代两种写法。对于本题一定要记住是有序链表,值相同的节点会在一起。
1.1 递归函数定义
递归最基本的是要明白递归函数的定义!
递归函数直接使用题目给出的函数deleteDuplicates(head),它的含义是删除以head作为开头的有序链表,值出现重复的节点。
1.2 递归终止条件
终止条件就是能想到的基本的、不用继续递归处理的case

  • 如果head为空,那么肯定没有值出现反复的节点,直接返回head;
  • 如果head.next为空,那么说明链表中只有一个节点,也没有值出现重复的节点,也直接返回head

1.3 递归调用
什么时候需要调用递归呢?我们考虑两种情况:

  • 如果head.val != head.next.val,说明头节点的值不等于下一个节点的值,所以当前的head节点必须保留;但是head.next节点要不要保留呢?我们还不知道,需要head.next进行递归,即对head.next作为头节点的链表,去除值重复的节点。所以head.next = self.deleteDuplicates(head.next)
  • 如果head.val == head.next.val,说明头节点的值等于下一个节点的值,所以当前的head,节点必须删除;但是head.next节点要不要删除呢?我们还不知道,需要一直向后遍历寻找与head.val不等的节点。与haed.val相等的这一段链表都要删除,因此返回deleteDuplicates(move)

1.4 返回结果
题目让我们返回删除了值重复的节点后剩余的链表,结合上面两种递归调用的情况。

  • 如果head.val != head.next.val,头节点需要保留,因此返回的是head
  • 如果head.val == head.next.val,头节点需要删除,需要返回的是deleteDuplicates(move)

迭代

方法二:一次遍历

这里说的一次遍历,是说一次遍历、一遍统计相邻节点的值是否相等,如果值相等就继续后移找到值不等的位置,然后删除值相等的这个区间
其实这个思路很简单,跟递归方法中的while语句跳过所有值相等的节点的思路是一样的:如果curr.val == cur.next.val说明两个相邻节点值相等,所以继续猴戏,一直找到cur.val !=cure.next.val,此时的cur.next就是值不等的节点;
代码中用到了一个常见的技巧:dummy节点,也叫做哑节点
它在链表的迭代写法中非常常见,因为对于本题而言,我们可能会删除头节点head,为了维护一个不变的头节点,所以我们添加了dummy,让dummy.next = head,这样即使头节点被删除了,那么操作dummy.next指向新的链表头部,所以最终返回的也是dummy.next

方法三:利用计数,两次遍历

这个做法忽略了链表有序这个性质,使用了两次遍历,第一次遍历统计每个节点的值出现的次数,第二次遍历的时候,如果发现head.next的val出现次数不是1次,则需要删除head.next

代码

递归:

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return head
        if head.val != head.next.val:
            head.next = self.deleteDuplicates(head.next)
        else:
            move = head.next
            while move and head.val == move.val:
                move = move.next
            return self.deleteDuplicates(move)
        return head

迭代:
一次遍历:

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return head
        dummy = ListNode(0)
        dummy.next = head
        pre = dummy
        cur = head
        while cur:
            while cur.next and cur.val ==cur.next.val:
                cur = cur.next
            if pre.next ==cur:
                pre = pre.next
            else:
                pre.next = cur.next
            cur =cur.next
        return dummy.next

两次遍历:

class Solution:
    def deleteDuplicates(self, head):
        dummy = ListNode(0)
        dummy.next = head
        val_list = []
        while head:
            val_list.append(head.val)
            head = head.next
        counter = collections.Counter(val_list)
        head = dummy
        while head and head.next:
            if counter[head.next.val] != 1:
                head.next = head.next.next
            else:
                head = head.next
        return dummy.next

复杂度分析

递归:
时间复杂度: O ( N ) O(N) O(N)
空间复杂度: O ( N ) O(N) O(N)

迭代:
一次遍历
时间复杂度: O ( N ) O(N) O(N)
空间复杂度: O ( 1 ) O(1) O(1)

两次遍历
时间复杂度: O ( N ) O(N) O(N)
空间复杂度: O ( N ) O(N) O(N)文章来源地址https://www.toymoban.com/news/detail-847334.html

到了这里,关于算法第四十一天-排除排序链表中的重复元素Ⅱ的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第四十一天 Java基础学习(三十五)

    一、JSP内置对象 ●内置对象 因为SP的本质是Servlet,在JSP文件经过转译之后,生成JAVA代码,在运行时JSP给我们准备好了九个可以直接使用而不用我们自己去new的对象,这九个对象我之为内置对象. 内置对象完全由SP自行去维护,我们直接使用即可。 ●九大内置对象 confia ;page ;

    2024年02月16日
    浏览(46)
  • 第四十一章 Unity 输入框 (Input Field) UI

    本章节我们学习输入框 (Input Field),它可以帮助我们获取用户的输入。我们点击菜单栏“GameObject”-“UI”-“Input Field”,我们调整一下它的位置,效果如下 我们在层次面板中发现,这个InputField UI元素包含两个子元素,一个是Placeholder,另一个是Text。如下所示 同样,我们查看

    2024年02月04日
    浏览(39)
  • 【从零开始学习JAVA | 第四十一篇】深入JAVA锁机制

    目录 前言:          引入: 锁机制:  CAS算法: 乐观锁与悲观锁: 总结: 在多线程编程中,线程之间的协作和资源共享是一个重要的话题。当多个线程同时操作共享数据时,就可能引发数据不一致或竞态条件等问题。为了解决这些问题,Java提供了强大的锁机制,使得

    2024年02月14日
    浏览(54)
  • 【LeetCode75】第四十一题 二叉搜索树中的搜索

    目录 题目: 示例: 分析: 代码: 题目给我们一个搜索二叉树,让我们找出节点值等于目标的节点并返回出去。 首先我们可以直接遍历整棵二叉树,找到值相同的节点就返回出去,不过这样就没有用到二叉搜索数的特性了。 二叉搜索数的特性就是,每一个节点的左子树上所

    2024年02月10日
    浏览(49)
  • 【正点原子STM32连载】 第四十一章 SPI实验 摘自【正点原子】APM32E103最小系统板使用指南

    1)实验平台:正点原子APM32E103最小系统板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420 3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban 本章将介绍使用APM32E103驱动板载的NOR Flash进行读写操作。通过本章的学习,读者将学习到使用SPI驱动

    2024年01月19日
    浏览(46)
  • 算法训练第四十五天

    279. 完全平方数 - 力扣(LeetCode) 总结:又是一个完全背包问题,自己这题的问题出在没有根据题意来初始化,只初始化了dp[1],因为感觉根据题意dp[0]不需要初始化导致错误 代码: 322. 零钱兑换 - 力扣(LeetCode) 总结:也是一种完全背包,不过与昨天的区别在于这题是求最少

    2024年02月11日
    浏览(39)
  • 算法训练第四十六天

    139. 单词拆分 - 力扣(LeetCode) 总结:自己一开始想的利用回溯来解决但是也考虑到可能会超时,从动归角度入手,自己没有弄清楚dp数组的含义而导致没有正确解决问题,此题的dp数组是当字符串的子串长度为i时,dp[i]表示能否用给定字典中的串表示出来,此题是一个排列的

    2024年02月11日
    浏览(43)
  • 算法训练第四十五天|70. 爬楼梯 (进阶)、322. 零钱兑换、279.完全平方数

    题目链接:70. 爬楼梯 (进阶) 参考:https://programmercarl.com/0070.%E7%88%AC%E6%A5%BC%E6%A2%AF%E5%AE%8C%E5%85%A8%E8%83%8C%E5%8C%85%E7%89%88%E6%9C%AC.html 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数

    2023年04月26日
    浏览(59)
  • 算法训练第四十三天|1049. 最后一块石头的重量 II 、494. 目标和、474.一和零

    题目链接:1049. 最后一块石头的重量 II 参考:https://programmercarl.com/1049.%E6%9C%80%E5%90%8E%E4%B8%80%E5%9D%97%E7%9F%B3%E5%A4%B4%E7%9A%84%E9%87%8D%E9%87%8FII.html 题目难度:中等 有一堆石头,每块石头的重量都是正整数。 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分

    2023年04月09日
    浏览(37)
  • 算法训练第四十二天|01背包问题 二维 、01背包问题 一维、416. 分割等和子集

    视频链接:https://www.bilibili.com/video/BV1cg411g7Y6/ 参考:https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html 对于面试的话,其实掌握01背包,和完全背包,就够用了,最多可以再来一个多重背包。 而完全背包又是也是01背包稍作变化而来,即:完全

    2024年02月01日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包