【Py/Java/C++三种语言详解】LeetCode每日一题240115【链表】LeetCode82、删除排序链表中的重复节点II

news2024/10/5 18:23:27

文章目录

  • 题目链接
  • 题目描述
  • 解题思路
  • 代码
    • python
    • Java
    • C++
    • 时空复杂度
  • 华为OD算法/大厂面试高频题算法练习冲刺训练

题目链接

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
  • 题目数据保证链表已经按升序 排列

解题思路

相比起前一题LeetCode83、删除排序链表中的重复节点,本题的区别在于要删除掉所有出现重复的节点

即假设存在链表1->2->2->2,那么值为1的节点应该作为当前节点cur,才能够顺利删除掉后面的所有值为2的节点。

同理,由于原链表的头节点可能被删除,所以本题需要设置哑节点dummyHead指向头节点,且当前节点cur初始化为哑节点,往后遍历

dummyHead = ListNode(0, head)   # 由于头节点可能被删除,设置哑节点指向头节点
cur = dummyHead                 # 当前节点cur从哑节点开始

由于需要判断下下个节点和下个节点的值是否相等,因此循环迭代的while条件为cur下下个节点存在,即

while(cur.next.next):
    pass

若当前节点cur的下个节点cur.next和下下个节点cur.next.next的值相等,则需要删除下下个节点,即

while(cur.next.next):           
    if cur.next.val == cur.next.next.val:
        cur.next = cur.next.next
    pass

由于下个节点cur.next也是被需要删除的节点,但是还不能在现在立刻删除,因为可能后面还存在第三个、第四个等值的节点需要删除,所以可以先用一个标记del_next_flag来标记,表示cur.next待会儿需要被删除。

while(cur.next.next):           
    if cur.next.val == cur.next.next.val:
        cur.next = cur.next.next
        del_next_flag = True
    pass

若当前节点cur的下个节点cur.next和下下个节点cur.next.next的值不相等,则需要考虑del_next_flag的值。若del_next_flag

  • True。说明cur.next是需要被删除的节点,删除之,且重置del_next_flag = False
  • False。说明cur.next不用被删除,cur可以前进到cur.next的位置。

综上整个while循环的过程为

while(cur.next.next):           
    if cur.next.val == cur.next.next.val:
        cur.next = cur.next.next
        del_next_flag = True
    else:
        if del_next_flag:
            cur.next = cur.next.next    
            del_next_flag = False
        else:
            cur = cur.next

注意在退出循环后,还需要再检查一次del_next_flag的值,以判断最后的尾节点是否需要删除。即

if del_next_flag:
    cur.next = cur.next.next 

最后返回哑节点的下一个节点,即为所有删除操作完毕之后的链表头节点。

代码

python

# 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]:
        if head is None:                # 排除特殊情况
            return None
        dummyHead = ListNode(0, head)   # 由于头节点可能被删除,设置哑节点指向头节点
        cur = dummyHead                 # 初始化当前节点为哑节点
        del_next_flag = False           # bool型标记,表示下一个节点cur.next是否需要删除
        while(cur.next.next):           # 循环迭代所有节点
            # 如果下一个节点的值等于下下个节点
            if cur.next.val == cur.next.next.val:
                # 删去下下个节点,将del_next_flag标记为True,用于后续删除下个节点
                cur.next = cur.next.next
                del_next_flag = True
            else:
                # 如果del_next_flag是True,说明下个节点也属于重复节点之一,需要删除
                # 删除后重置del_next_flag为False
                if del_next_flag:
                    cur.next = cur.next.next    
                    del_next_flag = False
                # 如果下个节点和下下个节点的值不等,且del_next_flag为False,
                # 则cur才可以前进
                else:
                    cur = cur.next
        # 退出循环后,如果del_next_flag为True,还需要再删去尾节点
        if del_next_flag:
            cur.next = cur.next.next  
        return dummyHead.next

Java

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
public class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null) {
            return null;
        }

        ListNode dummyHead = new ListNode(0, head);
        ListNode cur = dummyHead;
        boolean delNextFlag = false;

        while (cur.next != null && cur.next.next != null) {
            if (cur.next.val == cur.next.next.val) {
                cur.next = cur.next.next;
                delNextFlag = true;
            } else {
                if (delNextFlag) {
                    cur.next = cur.next.next;
                    delNextFlag = false;
                } else {
                    cur = cur.next;
                }
            }
        }

        if (delNextFlag) {
            cur.next = cur.next.next;
        }

        return dummyHead.next;
    }
}

C++

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if (head == nullptr) {
            return nullptr;
        }

        ListNode* dummyHead = new ListNode(0, head);
        ListNode* cur = dummyHead;
        bool delNextFlag = false;

        while (cur->next != nullptr && cur->next->next != nullptr) {
            if (cur->next->val == cur->next->next->val) {
                cur->next = cur->next->next;
                delNextFlag = true;
            } else {
                if (delNextFlag) {
                    cur->next = cur->next->next;
                    delNextFlag = false;
                } else {
                    cur = cur->next;
                }
            }
        }

        if (delNextFlag) {
            cur->next = cur->next->next;
        }

        return dummyHead->next;
    }
};

时空复杂度

时间复杂度:O(N)。仅需一次遍历链表

空间复杂度:O(1)


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1386365.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hotspot源码解析-第十九章-ClassLoaderData、符号表、字符串表的初始化

第十九章-ClassLoaderData初始化 讲解本章先从一张图开始 众所周知&#xff0c;Java类的相关信息都是存储在元空间中的&#xff0c;但是是怎么存储的&#xff0c;相信很多读者是不清楚的&#xff0c;这里就不得不涉及到ClassLoaderDataGraph、classLoader、classLoaderData&…

容器化postgres备份策略

文章目录 1. 策略和背景1.1 背景1.2 备份策略 2. docker-compose的修改2.1 挂载备份目录2.2 备份脚本3.3 重启容器 3. 定时任务 1. 策略和背景 1.1 背景 使用docker-compose管理的postgres数据库需要备份工作目录在 /data/postgres下 1.2 备份策略 要备份的库 shu_han 库 每…

vue3中组合式api的常用方法

vue3中组合式api的常用方法 记录一下vue3中常用的组合式api&#xff0c;包括计算属性computed、监听器watch及watchEffective 一、computed 作用&#xff1a;根据已有数据计算出新数据&#xff08;和Vue2中的computed作用一致&#xff09;。 <template><div class&…

JavaScript 异步编程解决方案-中篇

天下事有难易乎&#xff1f; 为之&#xff0c;则难者亦易矣&#xff1b;不为&#xff0c; 则易者亦难矣。人之为学有难易乎&#xff1f; 学之&#xff0c;则难者亦易矣&#xff1b;不学&#xff0c;则易者亦难矣。 async 函数 和promise then的规则一样 async function fun() …

HarmonyOS4.0——ArkUI应用说明

一、ArkUI框架简介 ArkUI开发框架是方舟开发框架的简称&#xff0c;它是一套构建 HarmonyOS / OpenHarmony 应用界面的声明式UI开发框架&#xff0c;它使用极简的UI信息语法、丰富的UI组件以及实时界面语言工具&#xff0c;帮助开发者提升应用界面开发效率 30%&#xff0c;开发…

element + table 每两行对比相同值列合并

在开始之前先要明确几个概念&#xff1a; 保持不变&#xff1a;{ rowspan: 1, colspan: 1 } 删除一个单元格&#xff1a;{ rowspan: 0, colspan: 0 } 合并一个单元格&#xff1a;{ rowspan: 2, colspan: 1 } <template><div><el-table:data"tableData&quo…

二叉树的遍历 Java

二叉树的遍历 递归法前序遍历中序遍历后序遍历改进 迭代法前序、后序遍历中序遍历 Java 中 null、NULL、nullptr 区别 public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode left, Tree…

LLM推理部署(七):FireAttention——通过无损量化比vLLM快4倍

Mixtral作为第一个在数万亿tokens上训练的OSS模型&#xff0c;最近在人工智能社区掀起了波澜&#xff0c;它支持“混合专家”&#xff08;MoE&#xff09;&#xff0c;并且训练和推理速度非常快。 Fireworks AI是第一个托管Mixtral的平台&#xff0c;在Mixtral公开发布之前就托…

小程序中使用微信同声传译插件实现语音识别、语音合成、文本翻译功能----语音识别(一)

官方文档链接&#xff1a;https://mp.weixin.qq.com/wxopen/plugindevdoc?appidwx069ba97219f66d99&token370941954&langzh_CN#- 要使用插件需要先在小程序管理后台的设置->第三方设置->插件管理中添加插件&#xff0c;目前该插件仅认证后的小程序。 语音识别…

༺༽༾ཊ—游戏-01_2D-开发—ཏ༿༼༻

首先利用安装好的Unity Hub创建一个unity 2D&#xff08;URP渲染管线&#xff09;项目 选择个人喜欢的操作格局&#xff08;这里采用2 by 3&#xff09; 在Project项目管理中将双栏改为单栏模式&#xff08;个人喜好&#xff09; 找到首选项&#xff08;Preferences&#xff09…

2024 解决matplotlib中文字体问题

第一种代码&#xff08;失败代码&#xff09; import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib.font_manager import FontPropertiesfont_path /Users/huangbaixi/Desktop/SimHei.ttfdef plot_demo():#print(mpl.get_cachedir())# 绘制折线图font…

【记忆化搜索】

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;【LeetCode】winter vacation training 前言 记忆化搜索是一种优化搜索算法的方法&#xff0c;它可…

Apache StringUtils:Java字符串处理工具类

简介 在我们的代码中经常需要对字符串判空&#xff0c;截取字符串、转换大小写、分隔字符串、比较字符串、去掉多余空格、拼接字符串、使用正则表达式等等。如果只用 String 类提供的那些方法&#xff0c;我们需要手写大量的额外代码&#xff0c;不然容易出现各种异常。现在有…

GL Logger和CANFDLog-OTL-128两款记录仪都是如何实现高效的报文录制的?

GL Logger是Vector推出的记录CAN/CAN FD、LIN、FlexRay和MOST数据通信的工具。以GL2400为例带着大家一步步地实现路试过程中通过整车OBD口进行CAN/CANFD报文的录制。 Step1 设备配置 设备配置即设备录制方式、录制内容、设备休眠唤醒策略等。 ▷ 打开Vector Logger Configurat…

调试ad5245的总结

调试ad5245的总结 这个ad5245是通过IIC与FPGA进行通信的&#xff0c;首先要理解IIC协议。 经验总结&#xff1a; 1、SCL和SDA端的要有上拉电阻&#xff0c;且上拉电阻能正常工作&#xff1b; 2、要往SDA数据线上写三个字节才能调节ad5245的电阻值&#xff0c;第三个字节就是…

html中的flex是什么?——弹性布局

在HTML中&#xff0c;flex是一种布局方式&#xff0c;用于处理容器中的子元素的布局。它是CSS3的一部分&#xff0c;也被称为弹性布局。 通过使用flex布局&#xff0c;可以将容器中的子元素进行灵活的定位和扩展&#xff0c;以适应不同的屏幕尺寸和设备。它提供了一种简单而强…

flink 1.18 sql gateway /sql gateway jdbc

一 sql gateway 注意 之所以直接启动gateway 能知道yarn session 主要还是隐藏的配置文件&#xff0c;但是配置文件可以被覆盖&#xff0c;多个session 保留最新的applicationid 1 安装flink &#xff08;略&#xff09; 2 启动sql-gatway(sql-gateway 通过官网介绍只能运行…

【时光记:2023的心灵旅程】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

tree数据处理

接口获取数据oldArr [{"deptCode": "01","parentCode": "000","sortKey": 4,"deptName": "办公室&#xff08;党委办公室、董事会办公室&#xff09;","children": [{"deptCode":…

九、Qt C++ 毕业设计 数据库相关

《一、QT的前世今生》 《二、QT下载、安装及问题解决(windows系统)》《三、Qt Creator使用》 ​​​ 《四、Qt 的第一个demo-CSDN博客》 《五、带登录窗体的demo》 《六、新建窗体时&#xff0c;几种窗体的区别》 《七、Qt 信号和槽》 《八、Qt C 毕业设计-CSDN博客》 …