【leetcode热题】排序链表

给你链表的头结点 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 = []
输出:[]

解法一

归并排序需要一个辅助方法,也就是对两个有序链表进行合并,在 21 题 已经讨论过。

至于归并排序的思想,这里就不多讲了,本科的时候用 Scratch 做过一个演示视频,感兴趣的可以参考 这里,哈哈。

那就直接放代码了。因为归并排序是一半一半的进行,所以需要找到中点。最常用的方法就是快慢指针去找中点了。

ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode fast = dummy;
ListNode slow = dummy;
while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;
}

上边的代码我加了一个 dummy 指针,就是想当节点个数是偶数的时候,让 slow 刚好指向前边一半节点的最后一个节点,也就是下边的状态。

1    2    3    4^         ^slow      fast

如果 slow 和 fast 都从 head 开始走,那么当 fast 结束的时候,slow 就会走到后边一半节点的开头了。

当然除了上边的方法,在 这里 看到,还可以加一个 pre 指针,让它一直指向 slow 的前一个即可。

// step 1. cut the list to two halves
ListNode prev = null, slow = head, fast = head;while (fast != null && fast.next != null) {prev = slow;slow = slow.next;fast = fast.next.next;
}

他们的目的都是一样的,就是为了方便的把两个链表平均分开。

public ListNode sortList(ListNode head) {return mergeSort(head);
}private ListNode mergeSort(ListNode head) {if (head == null || head.next == null) {return head;}ListNode dummy = new ListNode(0);dummy.next = head;ListNode fast = dummy;ListNode slow = dummy;//快慢指针找中点while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}ListNode head2 = slow.next;slow.next = null;head = mergeSort(head);head2 = mergeSort(head2);return merge(head, head2);}private ListNode merge(ListNode head1, ListNode head2) {ListNode dummy = new ListNode(0);ListNode tail = dummy;while (head1 != null && head2 != null) {if (head1.val < head2.val) {tail.next = head1;tail = tail.next;head1 = head1.next;} else {tail.next = head2;tail = tail.next;head2 = head2.next;}}if (head1 != null) {tail.next = head1;}if (head2 != null) {tail.next = head2;}return dummy.next;}

当然严格的说,上边的解法空间复杂度并不是 O(1),因为递归过程中压栈是需要消耗空间的,每次取一半,所以空间复杂度是 O(log(n))

递归可以去改写成迭代的形式,也就是自底向上的走,就可以省去压栈的空间,空间复杂度从而达到 O(1),详细的可以参考 这里-with-o(1)-space-complextity-and-o(nlgn)-time-complextity) 。

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

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

相关文章

redis使用笔记

redis使用笔记 1、Redis简介1.1 含义1.2 功能1.3 特点 2. 常用的数据结构2.1 HASH 3 redis接口定义3.1 redisReply3.2 redisContext3.3 redisCommand 4 实践操作4.1 遇到问题4.1.1 Get哈希的时候返回error4.1.2 长度一直为0&#xff0c;str没法打印&#xff08;未解决&#xff…

css 用flex做成田字型

哈喽&#xff0c;各位小伙伴&#xff01;今天给大家来css控制div完成田字型样式&#xff0c;来&#xff0c;看看下面的效果图&#xff1a; 一看就知道你们想要代码了&#xff0c;不急。代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head>&…

如何保证 redis 的高并发和高可用?redis 的主从复制原理能介绍一下么?redis 的哨兵原理能介绍一下么?

目录 一、面试官心理分析 二、面试题剖析 1.Redis 主从架构 2.Redis replication 的核心机制 3.Redis 主从复制的核心原理 4.主从复制的断点续传 5.无磁盘化复制 6.过期 key 处理 7.复制的完整流程 8.全量复制 9.增量复制 10.heartbeat 11.异步复制 12.Redis 如何…

CAP告诉你系统没法做到完美,只能做到权衡和适当

一、CAP介绍 CAP原理&#xff0c;全称为Consistency&#xff08;一致性&#xff09;、Availability&#xff08;可用性&#xff09;和Partition tolerance&#xff08;分区容错性&#xff09;&#xff0c;是分布式系统设计中的基本原理。它强调了在设计分布式系统时&#xff0c…

Unity中使用C#以【拟牛顿法】来求解非线性方程组

python科学计算包中有一个fsolve函数来求解非线性方程组&#xff0c;那么C#中用什么包和什么api与之对应呢&#xff1f;本文仅针对拟牛顿法求解过程展开MathNet包中对应API的考察和测试。 一、案例1 1、方程组 2、python的解法 &#xff08;1&#xff09;代码 from scipy.o…

xlsx.js读取本地文件,按行转成数组数据

1.下包 //1. npm install xlsx //2. yarn add xlsx2.结构 <template><input type"file" change"onFileChange" /> </template>3.代码 <script> import * as XLSX from xlsxexport default {methods: {onFileChange (event) {/…

selenium高级应用

常见控件应用 复杂的控件操作1.操作Ajax选项2.滑动滑块操作 WebDriver的特殊操作元素class值包含空格property、attribute、text的区别定位动态id 截图功能页面截图页面截图&#xff0c;返回截图的二进制数据页面截图&#xff0c;返回base64的字符串截取指定元素。先定位元素&a…

计算机网络—以太网接口和链路配置

目录 1.拓扑图 2.以太网交换机基础配置 3.配置手动模式的链路聚合 4.配置静态 LACP 模式的链路聚合 5.配置文件 1.拓扑图 2.以太网交换机基础配置 华为交换机接口默认开启了自协商功能&#xff0c;需要手动配置S1与 S2上G0/0/9和G0/0/10接口的速率。 首先修改交换机的设…

深入理解Vue.js中的nextTick:实现异步更新的奥秘

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

代码随想录算法训练营第五十三天|1143.最长公共子序列 、1035.不相交的线、53. 最大子序和

文章目录 1.最长公共子序列2.不相交的线3.最大子序和 1.最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长公共子序列的长度。如果不存在公共子序列&#xff0c;返回 0。 一个字符串的子序列是指这样一个新的字符串&#xff1a;它是由原字符串…

两会声音|中国石化人大代表:要突出战略性新兴产业、未来产业的位置

十四届全国人大二次会议即将闭幕&#xff0c;“新质生产力”首次写入政府工作报告&#xff0c;并出现在了重要位置。政府工作报告主要从推动产业链供应链优化升级、积极培育新兴产业和未来产业、深入推进数字经济创新发展等三个方面进行了阐述和规划。 全国两会期间&#xff0c…

C语言 --- 指针(5)

目录 一.sizeof和strlen对比 1.sizeof 2.strlen 3.strlen 和sizeof的对比 二.数组和指针笔试题目详解 回顾&#xff1a;数组名的理解 1.一维数组 2.字符数组 代码1&#xff1a; 代码2&#xff1a; 代码3&#xff1a; 代码4&#xff1a; 代码5&#xff1a; 代码6&am…