LeetCode hot 力扣热题100 排序链表

归并忘了 直接抄!

class Solution { // 定义一个 Solution 类,包含链表排序的相关方法。// 使用快慢指针找到链表的中间节点,并断开链表为两部分ListNode* middleNode(ListNode* head) { ListNode* slow = head; // 慢指针 slow 初始化为链表头节点ListNode* fast = head; // 快指针 fast 初始化为链表头节点while (fast->next && fast->next->next) { // 当 fast 指针还能向前走两步时循环slow = slow->next; // slow 每次向前移动一步fast = fast->next->next; // fast 每次向前移动两步}ListNode* mid = slow->next; // 找到中间节点的下一节点,将其作为右半部分的头节点slow->next = nullptr; // 将左半部分的最后一个节点的 next 指针置为 nullptr,断开链表return mid; // 返回右半部分的头节点 mid}// 合并两个有序链表,返回合并后的链表头节点ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {ListNode dummy; // 定义一个哨兵节点,简化合并逻辑ListNode* cur = &dummy; // cur 用于构建新链表,初始指向哨兵节点while (list1 && list2) { // 当两个链表都不为空时进行合并if (list1->val < list2->val) { // 如果 list1 的当前值小于 list2 的当前值cur->next = list1; // 将 list1 的节点加入新链表list1 = list1->next; // list1 指针向后移动} else { // 否则,将 list2 的节点加入新链表cur->next = list2;list2 = list2->next; // list2 指针向后移动}cur = cur->next; // cur 指针向后移动}cur->next = list1 ? list1 : list2; // 将剩余的非空链表直接接到新链表末尾return dummy.next; // 返回新链表的头节点(哨兵节点的下一个节点)}public:// 链表归并排序的主函数ListNode* sortList(ListNode* head) {if (head == nullptr || head->next == nullptr) { // 如果链表为空或只有一个节点,直接返回return head;}ListNode* head2 = middleNode(head); // 使用 middleNode 函数分割链表,head2 是右半部分的头节点head = sortList(head); // 递归地对左半部分链表排序head2 = sortList(head2); // 递归地对右半部分链表排序return mergeTwoLists(head, head2); // 将两个有序链表合并为一个}
};

思路详解

这段代码实现了 归并排序(Merge Sort)在链表上的应用,通过递归的方式将链表分割成两个部分,然后排序并合并。

核心思路

1. 拆分链表

使用快慢指针(middleNode 函数)找到链表的中间节点,将链表拆分为两部分。

2. 递归排序

对拆分后的两部分链表分别递归调用 sortList,直到链表被拆分为单个节点(此时链表自然是有序的)。

3. 合并链表

使用双指针(mergeTwoLists 函数)将两个有序链表合并为一个有序链表。

代码分析

1. middleNode 函数(找到中间节点并断开链表)

ListNode* middleNode(ListNode* head) {

    ListNode* slow = head;

    ListNode* fast = head;

    while (fast->next && fast->next->next) {

        slow = slow->next;

        fast = fast->next->next;

    }

    ListNode* mid = slow->next; // 中间节点

    slow->next = nullptr;       // 断开链表

    return mid;

}

功能:找到链表的中间节点并断开链表。

原理:使用快慢指针:

• 快指针 fast 每次移动两步;

• 慢指针 slow 每次移动一步;

• 当 fast 到达链表末尾时,slow 指向链表的中间节点。

返回值:mid 是中间节点的指针,用于分割链表。

2. mergeTwoLists 函数(合并两个有序链表)

ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {

    ListNode dummy; // 哨兵节点,简化合并过程

    ListNode* cur = &dummy;

    while (list1 && list2) {

        if (list1->val < list2->val) {

            cur->next = list1;

            list1 = list1->next;

        } else {

            cur->next = list2;

            list2 = list2->next;

        }

        cur = cur->next;

    }

    cur->next = list1 ? list1 : list2; // 拼接剩余链表

    return dummy.next; // 返回合并后的链表

}

功能:将两个有序链表合并为一个有序链表。

原理:使用双指针逐个比较两个链表的节点值,将较小值的节点连接到新链表上,直到其中一个链表为空。

返回值:合并后的链表头指针。

3. sortList 函数(链表归并排序的入口)

ListNode* sortList(ListNode* head) {

    if (head == nullptr || head->next == nullptr) {

        return head; // 链表为空或只有一个节点,无需排序

    }

    ListNode* head2 = middleNode(head); // 分割链表

    head = sortList(head);              // 递归排序左部分

    head2 = sortList(head2);            // 递归排序右部分

    return mergeTwoLists(head, head2);  // 合并两个有序链表

}

功能:实现链表的归并排序。

分割链表

• 调用 middleNode 函数找到链表的中间节点,并将链表分为两部分。

• 比如 [4,2,1,3] 分为 [4,2] 和 [1,3]。

递归排序

• 递归地对两部分链表分别调用 sortList 进行排序。

• 递归终止条件是链表为空或只有一个节点。

合并链表

• 调用 mergeTwoLists 函数将两个有序链表合并为一个。

算法过程

递归是一种通过函数调用自身来解决问题的方式,它通常分为两部分:终止条件递推关系。每一层递归会在满足特定条件后返回结果,并将结果传递给上一层递归调用。下面以链表排序 sortList 函数为例,详细说明递归的每一层操作。

每一层递归如何工作

以链表 [4, 2, 1, 3] 为例,说明每一层递归的处理过程。

第 1 层递归

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

中间节点:middleNode 找到 mid = 1,链表被分为两部分:

• head = [4, 2]

• head2 = [1, 3]

递归调用

• 对 [4, 2] 和 [1, 3] 分别调用 sortList。

第 2 层递归

左侧递归

• 输入:head = [4, 2]

中间节点:mid = 2,链表分为:

• head = [4]

• head2 = [2]

递归调用

• 对 [4] 和 [2] 调用 sortList。

合并结果

• mergeTwoLists([4], [2]) 返回 [2, 4]。

右侧递归

• 输入:head = [1, 3]

中间节点:mid = 3,链表分为:

• head = [1]

• head2 = [3]

递归调用

• 对 [1] 和 [3] 调用 sortList。

合并结果

• mergeTwoLists([1], [3]) 返回 [1, 3]。

第 3 层递归

输入

• [4] 和 [2]:直接返回,因为链表只有一个节点或为空。

• [1] 和 [3]:同样直接返回。

回溯过程

第 2 层返回

• 左侧 [4, 2] 合并为 [2, 4]。

• 右侧 [1, 3] 合并为 [1, 3]。

第 1 层合并

• mergeTwoLists([2, 4], [1, 3]) 返回 [1, 2, 3, 4]。

总结

• 每层递归处理的是将链表分为两部分,并对每部分递归调用 sortList。

• 在回溯时,通过 mergeTwoLists 合并两个有序链表。

递归终止条件:链表为空或只有一个节点时,直接返回。

递归的深度:链表长度为 ,递归深度为 。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChromeOS 132 版本更新

ChromeOS 132 版本更新 1. 企业定制化 Chrome Web Store 管理员现在可以使用新设置定制 Chrome Web Store 以适应他们管理的用户&#xff0c;包括以下功能&#xff1a; 添加公司标志添加首页横幅和自定义公告策划扩展集合实施基于类别的控制 这些设置可以通过管理员控制台进…

力扣动态规划-5【算法学习day.99】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;建议灵神的题单和代码随想录&#xff09;和记录自己的学习过程&#xff0c;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关…

国内汽车法规政策标准解读:GB 44495-2024《汽车整车信息安全技术要求》

目录 背景 概述 标准适用范围 汽车信息安全管理体系要求&#xff08;第5章&#xff09; 信息安全基本要求&#xff08;第6章&#xff09; 信息安全技术要求&#xff08;第7章&#xff09; ◆ 外部连接安全要求&#xff1a; ◆通信安全要求&#xff1a; ◆软件升级安全…

Apache SeaTunnel 2.3.9 正式发布:多项新特性与优化全面提升数据集成能力

近日&#xff0c;Apache SeaTunnel 社区正式发布了最新版本 2.3.9。本次更新新增了Helm 集群部署、Transform 支持多表、Zeta新API、表结构转换、任务提交队列、分库分表合并、列转多行 等多个功能更新&#xff01; 作为一款开源、分布式的数据集成平台&#xff0c;本次版本通过…

EasyControl:首个登陆AWS Marketplace的中国MDM先锋

在全球数字化与移动化浪潮中&#xff0c;企业对安全、高效的移动设备管理&#xff08;MDM&#xff09;需求日益增长。EasyControl作为国内MDM领域的佼佼者&#xff0c;凭借成熟的技术和创新的解决方案&#xff0c;成为国内首个成功上线亚马逊AWS Marketplace的MDM产品&#xff…

OpenCV简介、OpenCV安装

OpenCV简介、OpenCV安装 本文目录&#xff1a; 零、时光宝盒 一、OpenCV简介 二、OpenCV图像处理基础知识 三、OpenCV-Python环境安装 2.1、纯python环境下安装OpenCV 2.2、Anaconda管理环境下安装 OpenCV 四、如何用OpenCV 中进行读取展示图像 五、OpenCV读取图像、显…

【语言处理和机器学习】概述篇(基础小白入门篇)

前言 自学笔记&#xff0c;分享给语言学/语言教育学方向的&#xff0c;但对语言数据处理感兴趣但是尚未入门&#xff0c;却需要在论文中用到的小伙伴&#xff0c;欢迎大佬们补充或绕道。ps&#xff1a;本文不涉及公式讲解&#xff08;文科生小白友好体质&#xff09;&#xff…

ARP 表、MAC 表、路由表、跨网段 ARP

文章目录 一、ARP 表1、PC2、路由器 - AR22203、交换机 - S57004、什么样的设备会有 ARP 表&#xff1f; 二、MAC 表什么样的设备会有 MAC 表&#xff1f; 三、路由表什么样的设备会有路由表&#xff1f; 四、抓取跨网段 ARP 包 所谓 “透明” 就是指不用做任何配置 一、ARP 表…

Spring的IoC、Bean、DI的简单实现,难度:※※※

目录 场景描述 第一步&#xff1a;初始化Maven项目 第二步&#xff1a;Maven导入Spring包&#xff08;给代码&#xff09; 第三步&#xff1a;创建Spring配置文件 第四步 创建Bean 第五步 简单使用Bean &#xff08;有代码&#xff09; 第六步 通过依赖注入使用Bean&…

wireshark工具简介

目录 1 wireshark介绍 2 wireshark抓包流程 2.1 选择网卡 2.2 停止抓包 2.3 保存数据 3 wireshark过滤器设置 3.1 显示过滤器的设置 3.2 抓包过滤器 4 wireshark的封包列表与封包详情 4.1 封包列表 4.2 封包详情 参考文献 1 wireshark介绍 wireshark是非常流行的网络…

C# OpenCvSharp 部署文档矫正,包括文档扭曲/模糊/阴影等情况

目录 说明 效果 模型 项目 代码 下载 参考 C# OpenCvSharp 部署文档矫正&#xff0c;包括文档扭曲/模糊/阴影等情况 说明 地址&#xff1a;https://github.com/RapidAI/RapidUnDistort 修正文档扭曲/模糊/阴影等情况&#xff0c;使用onnx模型简单轻量部署&#xff0c…

编辑器Vim基本模式和指令 --【Linux基础开发工具】

文章目录 一、编辑器Vim 键盘布局二、Linux编辑器-vim使用三、vim的基本概念正常/普通/命令模式(Normal mode)插入模式(Insert mode)末行模式(last line mode) 四、vim的基本操作五、vim正常模式命令集插入模式从插入模式切换为命令模式移动光标删除文字复制替换撤销上一次操作…

LeetCode 110.平衡二叉树

题目描述 给定一个二叉树&#xff0c;判断它是否是平衡二叉树。 示例 1&#xff1a; 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,3,3,null,null,4,4] 输出&#xff1a;false 示例 3&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;true 提示&#xff1a; …

Asp .Net Core 实现微服务:集成 Ocelot+Nacos+Swagger+Cors实现网关、服务注册、服务发现

什么是 Ocelot ? Ocelot是一个开源的ASP.NET Core微服务网关&#xff0c;它提供了API网关所需的所有功能&#xff0c;如路由、认证、限流、监控等。 Ocelot是一个简单、灵活且功能强大的API网关&#xff0c;它可以与现有的服务集成&#xff0c;并帮助您保护、监控和扩展您的…

Express中间件

目录 Express中间件 中间件的概念 next函数 全局中间与局部中间件 多个中间件 中间的5个注意事项 中间的分类 应用级中间件 路由级中间件 错误级中间件 Express内置中间件 express.json express.urlencoded 第三方中间件​编辑 自定义中间件 Express中间件 中间…

Linux 高级路由与流量控制-用 tc qdisc 管理 Linux 网络带宽

大家读完记得觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 此分享内容比较专业&#xff0c;很多与硬件和通讯规则及队列&#xff0c;比较底层需要有技术功底人员深入解读。 Linux 的带宽管理能力 足以媲美许多高端、专用的带宽管理系统。 1 队列&#xff0…

要获取本地的公网 IP 地址(curl ifconfig.me)

文章目录 通过命令行查询&#xff08;适用于 Linux/Mac/Windows&#xff09;Linux/MacWindows 注意事项 要获取本地的公网 IP 地址&#xff0c;可以通过以下简单的方法&#xff1a; 通过命令行查询&#xff08;适用于 Linux/Mac/Windows&#xff09; Linux/Mac 打开终端。输入…

项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(七)

文章目录 一、题库管理模块实现1、新增题目功能实现1.1 页面设计1.2 前端功能实现1.3 后端功能实现1.4 效果展示2、题目列表功能实现2.1 页面设计2.2 前端功能实现2.3 后端功能实现2.3.1 后端查询题目列表接口实现2.3.2 后端编辑试题接口实现2.4 效果展示二、代码下载一、题库管…

Python文本处理:LDA主题聚类模型

一、模型简介 LDA&#xff08;Latent Dirichlet Allocation&#xff09;是一种生成式概率模型&#xff0c;用于发现文本数据中隐藏的主题分布。本项目基于Python实现LDA主题模型&#xff0c;包含文本预处理、最佳主题数目选择、关键词提取、词云生成以及PyLDAvis可视化等步骤。…

4.JoranConfigurator解析logbak.xml

文章目录 一、前言二、源码解析GenericXMLConfiguratorlogback.xml解析通过SaxEvent构建节点model解析model节点DefaultProcessor解析model 三、总结 一、前言 上一篇介绍了logback模块解析logback.mxl文件的入口, 我们可以手动指定logback.xml文件的位置, 也可以使用其它的名…