leetcode 148. 排序链表 中等
给你链表的头结点 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 = [] 输出:[]
分析:
方法一:将链表的所有元素存放在数组中进行排序,再将排好序的数值依次放到链表里。
//方法一
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
int cmp(const void *a,const void *b)
{int *aa=(int*)a;int *bb=(int*)b;return *aa-*bb;
}struct ListNode* sortList(struct ListNode* head) {if(head==NULL)return NULL;struct ListNode *p=head;int num[50010]={0},t=0;while(p!=NULL)num[t++]=p->val,p=p->next;qsort(num,t,sizeof(int),cmp);p=head;int l=0;while(p!=NULL)p->val=num[l++],p=p->next;return head;
}
方法二:快速排序。
找到链表中的最大值和最小值,以它们的平均数mid作为分界值,小于等于mid的放到链表h1,大于mid的放到链表h2,之后再把h2挂在h1的后面即可。
//方法二 快速排序
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* sortList(struct ListNode* head) {if(head==NULL)return NULL;if(head->next==NULL)return head;struct ListNode *prehead=(struct ListNode*)malloc(sizeof(struct ListNode));prehead->next=head;struct ListNode *h1=(struct ListNode*)malloc(sizeof(struct ListNode));struct ListNode *h2=(struct ListNode*)malloc(sizeof(struct ListNode));h1->next=h2->next=NULL;int l=head->val,r=head->val;while(head->next!=NULL){head=head->next;l=fmin(l,head->val);r=fmax(r,head->val);}if(l==r){struct ListNode *p=prehead->next;free(prehead);free(h1);free(h2);return p; }int mid=(l+r)>>1;head=prehead->next;struct ListNode *p=head;while(head!=NULL){p=head;head=head->next;if(p->val<=mid)p->next=h1->next,h1->next=p;else p->next=h2->next,h2->next=p;}h1->next=sortList(h1->next);h2->next=sortList(h2->next);p=h1;while(p->next!=NULL)p=p->next;p->next=h2->next;struct ListNode *ans=h1->next;free(prehead);free(h1);free(h2);return ans;
}
方法三:自顶向下归并排序。
- 找到链表的中点,以中点为分界,将链表拆分成两个子链表。寻找链表的中点可以使用快慢指针的做法,快指针每次移动 2 步,慢指针每次移动 1 步,当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点。
- 对两个子链表分别排序。
- 将两个排序后的子链表合并,得到完整的排序后的链表。
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* sortList(struct ListNode* head) {if(head==NULL)return NULL;if(head->next==NULL)return head;struct ListNode *prehead=(struct ListNode*)malloc(sizeof(struct ListNode));prehead->next=head;struct ListNode *fast,*low;fast=low=prehead;while(fast->next!=NULL){low=low->next;fast=fast->next;if(fast->next!=NULL)fast=fast->next;}if(fast==low){free(prehead);return fast;}struct ListNode *h1=(struct ListNode*)malloc(sizeof(struct ListNode));struct ListNode *h2=(struct ListNode*)malloc(sizeof(struct ListNode));h1->next=head;h2->next=low->next;low->next=NULL;h1->next=sortList(head);h2->next=sortList(h2->next);struct ListNode *h=(struct ListNode*)malloc(sizeof(struct ListNode));struct ListNode *p,*q,*r;p=h1->next,q=h2->next,r=h;while(p!=NULL||q!=NULL){if(p==NULL&&q!=NULL)r->next=q,q=q->next;else if(p!=NULL&&q==NULL)r->next=p,p=p->next;else if(p->val<q->val)r->next=p,p=p->next;else r->next=q,q=q->next;r=r->next;}//r->next=NULL;p=h->next;free(h1);free(h2);free(h);return p;
}
方法四:自底向上归并排序
具体做法如下。
- 用 subLength 表示每次需要排序的子链表的长度,初始时 subLength=1。
- 每次将链表拆分成若干个长度为 subLength 的子链表(最后一个子链表的长度可以小于 subLength),按照每两个子链表一组进行合并,合并后即可得到若干个长度为 subLength×2 的有序子链表(最后一个子链表的长度可以小于 subLength×2)。
- 将 subLength 的值加倍,重复第 2 步,对更长的有序子链表进行合并操作,直到有序子链表的长度大于或等于 length,整个链表排序完毕。
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
//方法四 这里我把调试的部分也留下了
struct ListNode* sortList(struct ListNode* head) {if(head==NULL)return NULL;if(head->next==NULL)return head;struct ListNode *prehead=(struct ListNode*)malloc(sizeof(struct ListNode));prehead->next=head;int l=0,t=0;struct ListNode *p=head,*q=prehead;while(p!=NULL)l++,p=p->next;p=prehead->next;for(int i=1;i<l;i=fmin(i*2,l)){p=prehead->next;t=0;struct ListNode *index;while(p!=NULL){int l1=0,l2=0;struct ListNode *p1,*q1,*p2,*q2;p1=p;while(p!=NULL&&l1<i)l1++,q1=p,p=p->next;q1->next=NULL;if(p==NULL)break;p2=p;while(p!=NULL&&l2<i)l2++,q2=p,p=p->next;q2->next=NULL;
/*printf("i=%d l=%d\n",i,l);struct ListNode *test=p1;printf("p1=");while(test!=NULL)printf("%d ",test->val),test=test->next;printf("\n");test=p2;printf("p2=",i);while(test!=NULL)printf("%d ",test->val),test=test->next;printf("\n");
*/struct ListNode *h=(struct ListNode*)malloc(sizeof(struct ListNode));struct ListNode *r=h;while(p1!=NULL||p2!=NULL){if(p1==NULL&&p2!=NULL)r->next=p2,p2=p2->next;else if(p1!=NULL&&p2==NULL)r->next=p1,p1=p1->next;else if(p1->val<p2->val)r->next=p1,p1=p1->next;else r->next=p2,p2=p2->next;r=r->next;}if(t==0)prehead->next=h->next,t++,index=r;else index->next=h->next,index=r;;r->next=p;
/*test=h->next;printf("test=");while(test!=NULL)printf("%d ",test->val),test=test->next;printf("\n");
*/free(h);
/*printf("r=%d\n",r->val);test=p;printf("p=",i);while(test!=NULL)printf("%d ",test->val),test=test->next;printf("\n");test=prehead->next;printf("prehead=",i);while(test!=NULL)printf("%d ",test->val),test=test->next;printf("\n");
*/}}q=prehead->next;free(prehead);return q;
}
方法三、方法四来源:
作者:力扣官方题解
链接:https://leetcode.cn/problems/sort-list/solutions/492301/pai-xu-lian-biao-by-leetcode-solution/
相关文章:
leetcode 148. 排序链表 中等
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 示例 1: 输入:head [4,2,1,3] 输出:[1,2,3,4] 示例 2: 输入:head [-1,5,3,4,0] 输出:[-1,0,3,4,5]示例 3: …...
动态规划与贪心算法:核心区别与实例分析
动态规划与贪心算法:核心区别与实例分析 动态规划和贪心算法是计算机科学中用于解决优化问题的两种著名方法。它们各自的思路和应用场景有显著的区别,理解这些区别对解决相关问题至关重要。本文将详细探讨这两种算法的最优子结构、解法策略、适用场景&a…...
.NET 公共语言运行时(Common Language Runtime,CLR)
.NET 的公共语言运行时(Common Language Runtime,CLR)是 .NET Framework 和 .NET Core 的核心组件,负责运行和管理 .NET 程序。CLR 提供了一个高效、安全和稳定的执行环境,支持多种编程语言并处理各种系统级的任务。下…...
SpringBoot使用TraceId日志链路追踪
项目场景: 有时候一个业务调用链场景,很长,调了各种各样的方法,看日志的时候,各个接口的日志穿插,确实让人头大。为了解决这个痛点,就使用了TraceId,根据TraceId关键字进入服务器查询…...
YOLO11 旋转目标检测 | OBB定向检测 | ONNX模型推理 | 旋转NMS
本文分享YOLO11中,从xxx.pt权重文件转为.onnx文件,然后使用.onnx文件,进行旋转目标检测任务的模型推理。 用ONNX模型推理,便于算法到开发板或芯片的部署。 本文提供源代码,支持不同尺寸图片输入、支持旋转NMS过滤重复…...
PCL 点云拟合 拟合空间直线
目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 设置RANSAC算法参数 2.1.2拟合直线模型 2.1.3 提取拟合直线内点 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算法与项目实战案例汇总(长期更…...
我的创作纪念日-20241112-感谢困难
我的创作纪念日-20241112-感谢困难 一、机缘二、收获1、积累2、感谢困难 三、日常四、成就五、憧憬 一、机缘 我之前有一个自己的私人博客,但是后来发现CSDN的功能更强大,更专业,所以我就把自己博客内容转到CSDN上面来了。 二、收获 1、积累…...
苍穹外卖05-Redis相关知识点
目录 什么是Redis? redis中的一些常用指令 value的5种常用数据类型 各种数据类型的特点 Redis中数据操作的常用命令 字符串类型常用命令: 哈希类型常用命令 列表操作命令 集合操作命令 有序集合操作命令 通用命令 在java中操作Redis 环境…...
unity 玩家和炸弹切线计算方式
脚本挂在炸弹上! using System.Collections; using System.Collections.Generic; using UnityEngine;public class TargetDetaction : MonoBehaviour {private Transform PlayerTF;private Transform bomb;private float radius;private string Player "Play…...
【MySQL】MySQL中的函数之REGEXP_LIKE
在 MySQL 中,REGEXP_LIKE() 函数用于检查一个字符串是否与正则表达式匹配。不过需要注意的是,REGEXP_LIKE() 并不是所有版本的 MySQL 都支持的函数。这个函数是在 MySQL 8.0 版本中引入的。 基本语法 REGEXP_LIKE(str, pat [, match_type ])str: 要测试…...
跟着尚硅谷学vue2—进阶版4.0—Vuex1.0
5. Vuex 1. 理解 Vuex 1. 多组件共享数据-全局事件总线实现 红线是读,绿线是写 2. 多组件共享数据-vuex实现 vuex 不属于任何组件 3. 求和案例-纯vue版 核心代码 1.Count.vue <template><div><h1>当前求和为:{{ sum }}</h1&…...
深度学习服务器租赁AutoDL
省钱绝招 #AutoDL #GPU #租显卡...
excel常用技能
1.基础技能 1.1 下拉框设置 a. 选中需要设置的列或单元格,数据 ---》 数据验证 b.验证条件 ---> 序列(多个值逗号隔开) 1.2 进度条百分比显示设置 开始 ---> 条件格式 --->新建规则--->编辑规则 1.3 相对引用和绝对引用…...
Mac电脑中隐藏文件(即以 . 开头的文件/文件夹)的显示和隐藏的两种方法
方法一:使用电脑快捷键,步骤如下: 1、点击一下桌面,用来激活 Finder ; 2、同时按下 Command Shift 点,即 【Command Shift . 】; 3、 打开可能包含此类文件的文件夹,比如磁盘…...
【Linux】:进程信号(信号概念 信号处理 信号产生)
✨ 眼里有诗,自向远方 🌏 📃个人主页:island1314 🔥个人专栏:Linux—登神长阶 ⛺️ 欢迎关注:👍点赞 👂&#…...
Flink运行时架构以及核心概念
1.运行构架 1.提交作业后启动一个客户端进程,客户端解析参数(-d -t 等等),后进行封装由Actor通信系统提交,取消,更新任务给JobManager。 2.JobManager(进程)通信系统一个组件叫分发…...
用 Python 从零开始创建神经网络(五):损失函数(Loss Functions)计算网络误差
用损失函数(Loss Functions)计算网络误差 引言1. 分类交叉熵损失(Categorical Cross-Entropy Loss)2. 分类交叉熵损失类(The Categorical Cross-Entropy Loss Class)展示到目前为止的所有代码3. 准确率计算…...
[CKS] K8S RuntimeClass SetUp
最近准备花一周的时间准备CKS考试,在准备考试中发现有一个题目关于RuntimeClass创建和挂载的题目。 专栏其他文章: [CKS] Create/Read/Mount a Secret in K8S-CSDN博客[CKS] Audit Log Policy-CSDN博客 -[CKS] 利用falco进行容器日志捕捉和安全监控-CSDN博客[CKS…...
【Python爬虫实战】轻量级爬虫利器:DrissionPage之SessionPage与WebPage模块详解
🌈个人主页:易辰君-CSDN博客 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、SessionPage (一)SessionPage 模块的基本功能 (二)基本使…...
计算机网络-2.1物理层
文章目录 通信的基础概念信源、信宿、信号、信道码元、速率、波特带宽(Hz) 奈奎斯特采样定律和香农采样定律编码&解码,调制&解调常用的编码方法常用的调制方法 传输介质1. 导向型传输介质2. 非导向型传输介质物理层接口的特性 物理层…...
实战指南:基于快马AI生成可部署的、支持多游戏与数据库的账号管理应用
今天想和大家分享一个实战项目:用Python开发一个支持多游戏的账号管理器(俗称"lv上号器")。这个工具特别适合游戏多开玩家,能安全存储不同游戏的账号信息,还能一键登录不同游戏客户端。 项目需求分析 首先明…...
目录中不显示标题中间的软换行符Shift+Enter
文档中的标题过长时,通常使用ShiftEnter软换行符来给标题在合适的位置换行,以实现美观的排版效果。然而,插入软换行符会造成自动产生的目录中标题文本中间出现空格,如图所示:那么,如何让目录中不显示这个软…...
Go Context 取消信号传播机制剖析
Go Context 取消信号传播机制剖析 在并发编程中,如何优雅地控制协程的生命周期是一个关键问题。Go语言通过Context机制提供了一种统一的取消信号传播方式,使得跨协程、跨层级的任务取消变得简单高效。本文将深入剖析Context的取消信号传播机制ÿ…...
React - useEffect、useRef、Fragment
一、useEffect 1、基本介绍 useEffect 用于在函数式组件中执行副作用操作,用于替代类组件中的生命周期钩子 useEffect(() > {// 副作用操作return () > {// 清理函数(可选)}; }, [依赖项数组]);副作用操作:发送请求数据获取…...
用Simulink+Carsim复现论文:四轮转向后轮控制5种算法对比(附模型下载)
用SimulinkCarsim复现论文:四轮转向后轮控制5种算法对比(附模型下载) 在车辆动力学与控制领域,四轮转向技术正逐渐从豪华车型向主流市场渗透。不同于传统的前轮转向系统,四轮转向通过后轮主动参与转向,显著…...
IIS请求筛选规则实战:手把手教你用‘拒绝字符串’精准拦截SQL注入和恶意爬虫
IIS请求筛选规则实战:构建精准防御体系的完整指南 当你的网站遭遇SQL注入攻击时,服务器日志里那些可疑的 OR 11--字符串是否让你夜不能寐?面对每天数十万次的恶意爬虫扫描,是否觉得传统的防火墙规则力不从心?IIS的请求…...
汽车电子选型:RF430F5144CIRKVRQ1为什么适合发动机舱附近的应用
RF430F5144CIRKVRQ1:这颗77mm的QFN芯片,如何把13.56MHz NFC和MSP430 MCU塞进一颗汽车级SoCRF430F5144CIRKVRQ1来自德州仪器,是一颗高度集成的NFC传感器收发器SoC。它的核心价值很直接:把13.56MHz HF射频前端、16位MSP430超低功耗M…...
OpenSees数值模拟从入门到进阶:理论、代码与实践
OpenSees数值模拟从入门到进阶:理论、代码与实践 摘要 OpenSees(Open System for Earthquake Engineering Simulation)作为开源的地震工程模拟系统,凭借其强大的非线性分析能力和开放的架构,已成为结构地震响应分析领域的重要工具。本文系统介绍OpenSees数值模拟的基本原…...
Evolutionary Architecture by Example:如何避免过度工程化陷阱
Evolutionary Architecture by Example:如何避免过度工程化陷阱 【免费下载链接】evolutionary-architecture-by-example Navigate the complex landscape of .NET software architecture with our step-by-step, story-like guide. Unpack the interplay between m…...
UI设计入门指南——Figma新手必备操作全解析
1. Figma入门:从零到第一个设计稿 第一次打开Figma时,很多人会被满屏的英文界面和复杂工具栏吓到。其实我刚接触时也一样,但现在回头看,掌握基础操作只需要30分钟。Figma作为目前最流行的UI设计工具,最大的优势就是零门…...
