数据结构之线性表——LeetCode:82. 删除排序链表中的重复元素 II,21. 合并两个有序链表,23. 合并 K 个升序链表

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

题目描述

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

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

运行代码

class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {if (!head) {return head;}ListNode* dummy = new ListNode(0, head);ListNode* cur = dummy;while (cur->next && cur->next->next) {if (cur->next->val == cur->next->next->val) {int x = cur->next->val;while (cur->next && cur->next->val == x) {cur->next = cur->next->next;}}else {cur = cur->next;}}return dummy->next;}
};

代码思路

  • 首先,处理输入链表为空的情况,如果 head 为 nullptr,直接返回 head
  • 创建一个虚拟头节点 dummy,并将其 next 指针指向输入链表的头节点 head。这样做是为了方便处理头节点可能被删除的情况。
  • 定义指针 cur 并初始化为 dummy,用于遍历链表并判断是否有重复节点。
  • 进入一个循环,只要 cur->next 和 cur->next->next 不为 nullptr,就继续循环。这个条件确保在检查是否有重复节点时,有足够的节点可供比较。
  • 如果发现当前节点 cur->next 的值等于下一个节点 cur->next->next 的值,说明存在重复节点:
    • 记录当前重复节点的值为 x
    • 进入一个循环,只要 cur->next 不为 nullptr 且其值等于 x,就将 cur->next 指针指向下一个节点的下一个节点,即跳过所有值为 x 的重复节点。
  • 如果没有发现重复节点,即当前节点 cur->next 的值不等于下一个节点 cur->next->next 的值,说明当前节点不重复,将 cur 指针向后移动一位,即 cur = cur->next
  • 循环结束后,返回虚拟头节点 dummy 的下一个节点,即为删除重复节点后的链表的头节点。

21. 合并两个有序链表

题目描述

21. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

运行代码

class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {ListNode* dum = new ListNode(0);ListNode* cur = dum;while (list1 != nullptr && list2 != nullptr) {if (list1->val < list2->val) {cur->next = list1;list1 = list1->next;}else {cur->next = list2;list2 = list2->next;}cur = cur->next;}cur->next = list1 != nullptr ? list1 : list2;return dum->next;}
};

代码思路

一、整体方法概述

这段代码的目的是合并两个升序链表为一个新的升序链表。它通过比较两个链表当前节点的值,将较小值的节点依次连接到新链表中,直到其中一个链表遍历完,然后将剩余的链表连接到新链表的末尾。

二、函数分析

  • 首先,创建一个虚拟头节点 dum,并将指针 cur 初始化为指向 dum。虚拟头节点的作用是方便返回合并后的链表,避免处理头节点为空的特殊情况。
  • 进入一个循环,只要 list1 和 list2 都不为 nullptr,就继续循环。这个循环的目的是逐个比较两个链表的节点值,并将较小值的节点连接到新链表中。
  • 在循环中,如果 list1 当前节点的值小于 list2 当前节点的值,那么将 cur 的 next 指针指向 list1,然后将 list1 指针向后移动一位,即 list1 = list1->next。如果 list1 当前节点的值大于等于 list2 当前节点的值,那么将 cur 的 next 指针指向 list2,然后将 list2 指针向后移动一位,即 list2 = list2->next。无论哪种情况,都将 cur 指针向后移动一位,即 cur = cur->next
  • 循环结束后,说明其中一个链表已经遍历完。此时,判断 list1 是否为 nullptr,如果不是,则将 cur 的 next 指针指向 list1;如果是,则将 cur 的 next 指针指向 list2。这样就将剩余的链表连接到了新链表的末尾。
  • 最后,返回虚拟头节点 dum 的下一个节点,即为合并后的链表的头节点。

三、算法思路总结

该算法利用了两个链表已经有序的特点,通过比较节点值的方式逐步构建新的合并链表。时间复杂度取决于两个链表的总长度,为O(m+n) ,其中  m和n  分别是两个链表的长度。空间复杂度为O(1) ,因为只使用了有限的额外指针变量,不随输入规模增长。

23. 合并 K 个升序链表

题目描述

23. 合并 K 个升序链表

给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。

运行代码

/*** 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* mergeTwoLists(ListNode *a, ListNode *b) {if ((!a) || (!b)) return a ? a : b;ListNode head, *tail = &head, *aPtr = a, *bPtr = b;while (aPtr && bPtr) {if (aPtr->val < bPtr->val) {tail->next = aPtr; aPtr = aPtr->next;} else {tail->next = bPtr; bPtr = bPtr->next;}tail = tail->next;}tail->next = (aPtr ? aPtr : bPtr);return head.next;}ListNode* mergeKLists(vector<ListNode*>& lists) {ListNode *ans = nullptr;for (size_t i = 0; i < lists.size(); ++i) {ans = mergeTwoLists(ans, lists[i]);}return ans;}
};

代码思路

  1. mergeTwoLists 函数

    • 这个函数用于合并两个升序链表 a 和 b
    • 首先处理特殊情况,如果其中一个链表为空,直接返回另一个链表。
    • 创建一个虚拟头节点 head 和一个指向虚拟头节点的指针 tail。同时,定义指针 aPtr 和 bPtr 分别指向两个输入链表的头节点。
    • 进入一个循环,只要 aPtr 和 bPtr 都不为空,就继续循环。在循环中,比较 aPtr 和 bPtr 所指节点的值,将较小值的节点连接到 tail->next,并相应地移动较小值节点的指针和 tail 指针。
    • 循环结束后,将剩余的非空链表连接到 tail->next
    • 最后,返回虚拟头节点 head 的下一个节点,即为合并后的链表的头节点。
  2. mergeKLists 函数

    • 这个函数用于合并 k 个升序链表。
    • 定义指针 ans 初始化为 nullptr,用于存储合并后的链表。
    • 遍历输入的链表数组 lists,每次将当前的合并结果 ans 和数组中的一个链表进行合并,更新 ans 为新的合并结果。
    • 最终,返回 ans,即合并后的链表的头节点。

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

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

相关文章

招联金融秋招内推喇--18薪

【投递方式】 直接扫下方二维码&#xff0c;或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus&#xff0c;使用内推码 igcefb 投递 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策划 产品运营…

三个视觉领域常用数据标注工具:labelImg 解压安装基础使用、 label-studio 的安装和基础使用【检测数据标注】

&#x1f947; 版权: 本文由【墨理学AI】原创、在CSDN首发、各位大佬、敬请查阅&#x1f389; 声明: 作为全网 AI 领域 干货最多的博主之一&#xff0c;❤️ 不负光阴不负卿 ❤️ 本次博文主要对如下三个视觉领域常用数据标注工具进行初步整理 labelImglabel-studio 工具Robo…

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-22

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-22 引言: 全球最热销的国产游戏-《黑神话: 悟空》不仅给世界各地玩家们带来愉悦&#xff0c;而且对计算机人工智能研究也带来新的思考。在本期的论文速读中&#xff0c;我们带来一篇关于视觉语言模型&#xff0…

想学习下Python和深度学习,Python需要学习到什么程度呢?

想要学习Python和深度学习&#xff0c;Python的学习程度需要达到能够熟练运用这门语言进行编程&#xff0c;并能够理解和实现深度学习模型的基本构建和训练过程。以下是一些推荐的书籍&#xff0c;可以帮助你系统地学习Python和深度学习&#xff1a; Python学习推荐书籍 《Py…

Ubuntu清理内存导致的一系列错误及解决方法

文章目录 火狐浏览器和pycharm消失打不开 安不上 卸不掉后记 火狐浏览器和pycharm消失 打不开 安不上 卸不掉 清理内存后&#xff0c;火狐和pycharm的图标都消失了&#xff0c;在终端输入Firefox显示无法打开 应当先snap install firefox&#xff0c;然而snap install firefo…

python全栈学习记录(十六)模块与包

模块与包 文章目录 模块与包一、模块1.模块的导入方式2.模块的循环导入问题3.搜索路径与优先级 二、包1.包的使用2.绝对导入与相对导入 三、一般工程的开发目录规范 一、模块 模块是一系列功能的集合体&#xff0c;常见的模块形式&#xff08;自定义模块、第三方模块、内置模块…

【Oracle篇】SQL执行计划之访问路径(含表级别、B树索引、位图索引、簇表四大类访问路径)(第三篇,总共七篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

【自动驾驶】决策规划算法(二)参考线模块Ⅰ| 平滑算法与二次规划

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

dhtmlxGantt 甘特图 一行展示多条任务类型

效果如图: 后台拿到数据 处理之后如图: 含义: 如上图所示, 如果一行需要展示多个 需要给父数据的那条添加render:split属性, 子数据的parent为父数据的Id即可 切记 父数据的id 别为0 为0 时 会出现错乱 因为有些小伙伴提出分段展示的数据结构还是有点问题,下面展示一个完整…

如何在 Apache 中仅开启 TLS 1.3 / TLS1.2 ?

互联网之所以运行良好&#xff0c;是因为它可以安全地发送数据&#xff0c;这要归功于传输层安全(TLS)等技术。TLS 是安全套接字层(SSL)的新版本&#xff0c;它有助于保持网络流量的安全。本文将讨论 TLS 1.3 和 1.2&#xff0c;它们比旧版本更好、更快。 使用这些协议的一个流…

Java继承教程!(o|o)

Java 继承 Java面向对象设计 - Java继承 子类可以从超类继承。超类也称为基类或父类。子类也称为派生类或子类。 从另一个类继承一个类非常简单。我们在子类的类声明中使用关键字extends&#xff0c;后跟超类名称。 Java不支持多重继承的实现。 Java中的类不能有多个超类。…

SwiftUI 实现关键帧动画

实现一个扫描二维码的动画效果&#xff0c;然而SwiftUI中没有提供CABasicAnimation 动画方法&#xff0c;该如何实现这种效果&#xff1f;先弄清楚什么关键帧动画&#xff0c;简单的说就是指视图从起点至终点的状态变化&#xff0c;可以是形状、位置、透明度等等 本文提供了一…

pytorch学习笔记二:用pytorch神经网络模型做气温预测、分类任务构建

文章目录 一、搭建pytorch神经网络进行气温预测1&#xff09;基础搭建2&#xff09;实际操作标识特征和标签3&#xff09;构建成标准化的预处理数据&#xff08;做标准化收敛速度更快&#xff09; 二、按照建模顺序构建完成网络架构1&#xff09;np.array格式的标签(y)和特征(x…

Spring Boot管理用户数据

目录 学习目标前言Thymeleaf 模板JSON 数据步骤 1: 创建 Spring Boot 项目使用 Spring Initializr 创建项目使用 IDE 创建项目 步骤 2: 添加依赖步骤 3: 创建 Controller步骤 4: 新建index页面步骤 5: 运行应用程序 表单提交步骤 1: 添加 Thymeleaf 依赖在 Maven 中添加依赖 步…

Github 2024-09-22 php开源项目日报 Top10

根据Github Trendings的统计,今日(2024-09-22统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量PHP项目10Blade项目1Coolify: 开源自助云平台 创建周期:1112 天开发语言:PHP, Blade协议类型:Apache License 2.0Star数量:10527 个Fork数量…

串的存储实现方法(与链表相关)

一、 定义 字符串是由零个&#xff08;空串&#xff09;或多个字符组成的有限序列。 eg:S"Hello World!" 串相等&#xff1a;两个串长度相等并且对应位置的字符都相等时&#xff0c;两个串才相等。 二、串的存储实现 2.1 定长顺序串 2.2 堆串 和定长顺序串的…

nodejs 014: React.FC 与 Evergreen(常青树) React UI 框架的的Dialog组件

React.FC React.FC是React中用于定义函数组件“Function Component”的类型。它代表&#xff0c;可以帮助你在TypeScript中提供类型检查和自动补全。使用React.FC时&#xff0c;可以明确指定组件的props类型&#xff0c;并且它会自动推导children属性。下面是一个使用 React.F…

二、MySQL环境搭建

文章目录 1. MySQL的卸载步骤1&#xff1a;停止MySQL服务步骤2&#xff1a;软件的卸载步骤3&#xff1a;残余文件的清理步骤4&#xff1a;清理注册表&#xff08;选做&#xff09;步骤5&#xff1a;删除环境变量配置 2. MySQL的下载、安装、配置2.1 MySQL的4大版本2.2 软件的下…

Ubuntu以及ROS的一些方便设置及使用

目录 增加环境变量 取消终端sudo密码 关闭开机密码 编写sh文件 虚拟环境的启用与关闭 launch文件小技巧 增加环境变量 1.在home目录下按ctrlh打开隐藏文件&#xff0c;打开.bashrc直接修改即可 2.输入gedit/vim ~/.bashrc修改即可 对于source ~/.bashrc这条指令只是适用…

从零开始讲DDR(5)——读懂Datasheet

对于开发人员来说&#xff0c;需要根据实际场景和使用的需要&#xff0c;使用不同厂家&#xff0c;不同型号的DDR&#xff0c;虽然原理上大同小异&#xff0c;但是还是有一些细节上的需要注意的地方&#xff0c;接触一个新的DDR芯片&#xff0c;首先就是需要找到对应的datashee…