Swift实现高效链表排序:一步步解读

在这里插入图片描述
在这里插入图片描述

文章目录

    • 前言
    • 摘要
    • 问题描述
    • 题解
      • 解题思路
      • Swift 实现代码
      • 代码分析
      • 示例测试与结果
    • 时间复杂度
    • 空间复杂度
    • 总结
    • 关于我们

前言

本题由于没有合适答案为以往遗留问题,最近有时间将以往遗留问题一一完善。

148. 排序链表

不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。

难度水平:中等

摘要

如何高效地对链表进行升序排序一直是算法中的经典问题之一。本文将深入解析如何使用Swift语言实现基于归并排序的链表排序算法,满足O(n log n)的时间复杂度和常数级空间复杂度的需求。同时,提供一段可运行的代码模块,帮助读者快速理解和实战。

问题描述

给定一个单链表的头结点head,要求对链表节点按升序排序并返回排序后的链表。

示例输入与输出

在这里插入图片描述

  • 示例 1:
    输入:head = [4, 2, 1, 3]
    输出:[1, 2, 3, 4]

在这里插入图片描述

  • 示例 2:
    输入:head = [-1, 5, 3, 4, 0]
    输出:[-1, 0, 3, 4, 5]

  • 示例 3:
    输入:head = []
    输出:[]

约束条件

  • 链表中的节点数范围:[0, 5 * 10^4]
  • 节点值范围:[-10^5, 10^5]

进阶要求

O(n log n)时间复杂度和常数级空间复杂度下完成链表排序。

题解

解题思路

归并排序是链表排序的理想选择,因其适合链表的顺序特性,并能够在O(n log n)时间复杂度内完成排序:

  1. 分割链表:递归地将链表从中间分为两个子链表,直到每个子链表只有一个节点。
  2. 合并有序链表:将两个已排序的链表按照升序合并成一个新的有序链表。

Swift 实现代码

class ListNode {var val: Intvar next: ListNode?init(_ val: Int) {self.val = valself.next = nil}
}func sortList(_ head: ListNode?) -> ListNode? {// 基本情况:空链表或只有一个节点guard let head = head, head.next != nil else {return head}// 使用快慢指针找到链表中点let mid = findMiddle(head)let rightHead = mid.nextmid.next = nil// 递归对两部分排序let left = sortList(head)let right = sortList(rightHead)// 合并排序后的两部分return merge(left, right)
}func findMiddle(_ head: ListNode) -> ListNode {var slow = headvar fast = headwhile fast.next != nil, fast.next?.next != nil {slow = slow.next!fast = fast.next!.next!}return slow
}func merge(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {let dummy = ListNode(0)var current = dummyvar l1 = l1var l2 = l2while let node1 = l1, let node2 = l2 {if node1.val < node2.val {current.next = node1l1 = node1.next} else {current.next = node2l2 = node2.next}current = current.next!}current.next = l1 ?? l2return dummy.next
}

代码分析

  1. 查找链表中点

    • 使用快慢指针找到链表的中间节点并将链表分成两部分。
    • 时间复杂度:O(n)
    • 空间复杂度:O(1)
  2. 递归排序

    • 不断分割链表直到只有一个节点时停止递归,然后逐步合并已排序的链表。
  3. 合并有序链表

    • 使用双指针遍历两个已排序链表,按值大小将节点逐个合并。
    • 时间复杂度:O(n)
    • 空间复杂度:O(1)

示例测试与结果

测试代码

func printList(_ head: ListNode?) {var current = headvar result: [Int] = []while let node = current {result.append(node.val)current = node.next}print(result)
}// 创建示例链表:[4, 2, 1, 3]
let head = ListNode(4)
head.next = ListNode(2)
head.next?.next = ListNode(1)
head.next?.next?.next = ListNode(3)// 调用排序函数
let sortedHead = sortList(head)// 打印结果
printList(sortedHead) // 输出:[1, 2, 3, 4]

测试结果

  • 输入:[4, 2, 1, 3]
    输出:[1, 2, 3, 4]
  • 输入:[-1, 5, 3, 4, 0]
    输出:[-1, 0, 3, 4, 5]
  • 输入:[]
    输出:[]

时间复杂度

  • 分割链表:每次递归调用的时间为O(n),最多递归log n次,总复杂度为O(n log n)
  • 合并链表:每层递归的合并操作处理所有节点,总复杂度为O(n)

总时间复杂度:O(n log n)

空间复杂度

  • 除递归调用外无需额外的存储空间,递归栈空间为O(log n)

总空间复杂度:O(log n)

总结

本文展示了如何在Swift中使用归并排序对链表进行高效排序,从分割链表到合并排序,算法步骤清晰,代码简洁。无论是处理小型链表还是大型数据集,该方法都能够在O(n log n)的时间内完成排序,是面试和实际开发中的理想解决方案。

关于我们

我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。

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

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

相关文章

【开篇】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…

qt QAnimationDriver详解

1、概述 QAnimationDriver是Qt框架中提供的一个类&#xff0c;它主要用于自定义动画帧的时间控制和更新。通过继承和实现QAnimationDriver&#xff0c;开发者可以精确控制动画的时间步长和更新逻辑&#xff0c;从而实现丰富和灵活的动画效果。QAnimationDriver与QAbstractAnim…

何时在 SQL 中使用 CHAR、VARCHAR 和 VARCHAR(MAX)

在管理数据库表时&#xff0c;考虑 CHAR、VARCHAR 和 VARCHAR(MAX) 是必不可少的。此外&#xff0c;使用正确的工具&#xff08;例如dbForge Studio for SQL Server&#xff09; &#xff0c;与数据库相关的任务都会变得更加容易。它是针对 SQL Server 专业人员的强大的一体化解…

20241127 给typecho文章编辑附件 添加视频 图片预览

Typecho在写文章时&#xff0c;如果一次性上传太多张图片可能分不清哪张&#xff0c;因为附件没有略缩图&#xff0c;无法实时阅览图片&#xff0c;给文章插入图片时很不方便。 编辑admin/file-upload.php 大约十八行的位置 一个while 循环里面,这是在进行html元素更新操作,在合…

Linux命令系列-常见查看系统资源命令

Linux命令系列-常见查看命令 进程管理内存管理磁盘空间管理网络管理主机系统 摘要&#xff1a;本文将对linux系统上常见的查看系统各种资源的命令进行介绍&#xff0c;包括du&#xff0c;df&#xff0c;netstat等命令。所有这些命令都有相关实验截图&#xff0c;实验平台为ubun…

【Python网络爬虫笔记】6- 网络爬虫中的Requests库

一、概述 Requests 是一个用 Python 语言编写的、简洁且功能强大的 HTTP 库。它允许开发者方便地发送各种 HTTP 请求&#xff0c;如 GET、POST、PUT、DELETE 等&#xff0c;并且可以轻松地处理请求的响应。这个库在 Python 生态系统中被广泛使用&#xff0c;无论是简单的网页数…

SolarCube: 高分辨率太阳辐照预测基准数据集

太阳能作为清洁能源在减缓气候变化中的作用日益凸显&#xff0c;其稳定的供应对电网管理至关重要。然而&#xff0c;太阳辐照受云层和天气变化的影响波动较大&#xff0c;给光伏电力的管理带来挑战&#xff0c;尤其是在调度、储能和备用系统管理方面。因此&#xff0c;精确的太…

对拍详细使用方法

对拍的作用 对于我们在学校OJ&#xff0c;cf&#xff0c;牛客…各种只提供少量测试数据的题目&#xff0c;常常交上代码常常超时&#xff0c;能写出正确的暴力代码而题目要求的时间复杂度更低。然而这时你写出了能通过样例且时间复杂度更低的代码&#xff0c;但交上去就是错误…

玄机应急:Apache日志分析Mysql应急Redis应急

目录 第二章&#xff1a;Linux的Apache日志分析 1、提交当天访问次数最多的IP&#xff0c;即黑客IP 2、黑客使用的浏览器指纹是什么&#xff0c;提交指纹的md5 3、查看index.php页面被访问的次数&#xff0c;提交次数&#xff1a; 4、查看黑客IP访问了多少次&#xff0c;提…

使用easyexcel导出复杂模板,同时使用bean,map,list填充

背景 在使用easyexcel导出时&#xff0c;如果遇到一个模板中同时存在 一部分是实体类中的字段&#xff0c;另外部分是列表的字段&#xff0c;需要特殊处理一下&#xff0c;比如下面的模板&#xff1a; 这里面 user&#xff0c; addr 是实体类&#xff08;或者map&#xff09…

otter 扩展

参见otter官方的说明&#xff1a;数据处理自定义&#xff0c;比如Extract , Transform的数据处理. 目前Select/Load不支持数据自定义处理。 Extract模块&#xff1a; 1.EventProcessor : 自定义数据处理&#xff0c;可以改变一条变更数据的任意内容。 2.FileResolver : 解决数…

STM32的CAN波特率计算

公式&#xff1a; CAN波特率 APB总线频率 / &#xff08;BRP分频器 1&#xff09;/ (SWJ BS1 BS2) SWJ一般为1。 例如STM32F407的&#xff0c;CAN1和CAN2都在在APB1下&#xff0c;频率是42000000 如果想配置成1M波特率&#xff0c;则计算公式为&#xff1a;

Z2400039基于Java-+ SpringBoot + vue 企业信息管理系统的设计与实现(源码 配置 PPT 文档 分享)

企业信息管理系统 1.项目描述2.项目结构后端&#xff08;Spring Boot&#xff09;前端&#xff08;Vue.js Element UI&#xff09; 2. 功能实现登录页首页系统管理岗位管理部门管理 3. 部署和运行注意事项 4.界面展示5.源码获取 1.项目描述 基于你的描述&#xff0c;这个项目…

hhdb数据库介绍(10-20)

监控 监控面板 监控面板为用户提供计算节点、服务器相关的监控功能&#xff0c;包含&#xff1a;计算节点服务状态、计算节点流量、计算节点服务器资源、其他服务器资源。 数据采集说明&#xff1a; 监控面板显示24小时内采集的数据&#xff08;需要放大显示&#xff0c;正…

医学机器学习:数据预处理、超参数调优与模型比较的实用分析

摘要 本文介绍了医学中的机器学习&#xff0c;重点阐述了数据预处理、超参数调优和模型比较的技术。在数据预处理方面&#xff0c;包括数据收集与整理、处理缺失值、特征工程等内容&#xff0c;以确保数据质量和可用性。超参数调优对模型性能至关重要&#xff0c;介绍了多种调…

SystemUI 下拉框 Build 版本信息去掉

需求及场景 去掉SystemUI 下拉框 Build 版本信息 如下图所示&#xff1a;去掉 12 &#xff08;SP1A.201812.016) 了解 去掉之前我们先了解它是个什么东西:其实就是一个Build RTM 信息显示 Android_12_build_SP1A.210812.016 修改文件 /frameworks/base/packages/Syste…

transformer学习笔记-词嵌入embedding原理

.在学习transformer的时候&#xff0c;可以看到&#xff0c;输入通常需要对词token进行embedding处理&#xff0c;如果没有先了解embedding的原理可能会有疑问&#xff0c;这个embedding&#xff0c;到底怎么来的&#xff0c;怎么就把一个token 变成一个矩阵&#xff0c;这个矩…

Apache Airflow 快速入门教程

Apache Airflow已经成为Python生态系统中管道编排的事实上的库。与类似的解决方案相反&#xff0c;由于它的简单性和可扩展性&#xff0c;它已经获得了普及。在本文中&#xff0c;我将尝试概述它的主要概念&#xff0c;并让您清楚地了解何时以及如何使用它。 Airflow应用场景 …

python+django自动化部署日志采用‌WebSocket前端实时展示

一、开发环境搭建和配置 # channels是一个用于在Django中实现WebSocket、HTTP/2和其他异步协议的库。 pip install channels#channels-redis是一个用于在Django Channels中使用Redis作为后台存储的库。它可以用于处理#WebSocket连接的持久化和消息传递。 pip install channels…

[MySQL]流程控制语句

流程控制语句需要借助存储过程才有效。关于存储过程&#xff0c;我会在后续的文章详述&#xff0c;本篇文章只是阐述流程控制语句。因此&#xff0c;大家只需要注意存储过程中相应的流程控制语句即可。 如果文中阐述不全或不对的&#xff0c;多多交流。 参考笔记三&#xff0c…