当前位置: 首页 > news >正文

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 &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4] 示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,3,4,5]示例 3&#xff1a; …...

动态规划与贪心算法:核心区别与实例分析

动态规划与贪心算法&#xff1a;核心区别与实例分析 动态规划和贪心算法是计算机科学中用于解决优化问题的两种著名方法。它们各自的思路和应用场景有显著的区别&#xff0c;理解这些区别对解决相关问题至关重要。本文将详细探讨这两种算法的最优子结构、解法策略、适用场景&a…...

.NET 公共语言运行时(Common Language Runtime,CLR)

.NET 的公共语言运行时&#xff08;Common Language Runtime&#xff0c;CLR&#xff09;是 .NET Framework 和 .NET Core 的核心组件&#xff0c;负责运行和管理 .NET 程序。CLR 提供了一个高效、安全和稳定的执行环境&#xff0c;支持多种编程语言并处理各种系统级的任务。下…...

SpringBoot使用TraceId日志链路追踪

项目场景&#xff1a; 有时候一个业务调用链场景&#xff0c;很长&#xff0c;调了各种各样的方法&#xff0c;看日志的时候&#xff0c;各个接口的日志穿插&#xff0c;确实让人头大。为了解决这个痛点&#xff0c;就使用了TraceId&#xff0c;根据TraceId关键字进入服务器查询…...

YOLO11 旋转目标检测 | OBB定向检测 | ONNX模型推理 | 旋转NMS

本文分享YOLO11中&#xff0c;从xxx.pt权重文件转为.onnx文件&#xff0c;然后使用.onnx文件&#xff0c;进行旋转目标检测任务的模型推理。 用ONNX模型推理&#xff0c;便于算法到开发板或芯片的部署。 本文提供源代码&#xff0c;支持不同尺寸图片输入、支持旋转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、感谢困难 三、日常四、成就五、憧憬 一、机缘 我之前有一个自己的私人博客&#xff0c;但是后来发现CSDN的功能更强大&#xff0c;更专业&#xff0c;所以我就把自己博客内容转到CSDN上面来了。 二、收获 1、积累…...

苍穹外卖05-Redis相关知识点

目录 什么是Redis&#xff1f; redis中的一些常用指令 value的5种常用数据类型 各种数据类型的特点 Redis中数据操作的常用命令 字符串类型常用命令&#xff1a; 哈希类型常用命令 列表操作命令 集合操作命令 有序集合操作命令 通用命令 在java中操作Redis 环境…...

unity 玩家和炸弹切线计算方式

脚本挂在炸弹上&#xff01; 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 中&#xff0c;REGEXP_LIKE() 函数用于检查一个字符串是否与正则表达式匹配。不过需要注意的是&#xff0c;REGEXP_LIKE() 并不是所有版本的 MySQL 都支持的函数。这个函数是在 MySQL 8.0 版本中引入的。 基本语法 REGEXP_LIKE(str, pat [, match_type ])str: 要测试…...

跟着尚硅谷学vue2—进阶版4.0—Vuex1.0

5. Vuex 1. 理解 Vuex 1. 多组件共享数据-全局事件总线实现 红线是读&#xff0c;绿线是写 2. 多组件共享数据-vuex实现 vuex 不属于任何组件 3. 求和案例-纯vue版 核心代码 1.Count.vue <template><div><h1>当前求和为&#xff1a;{{ sum }}</h1&…...

深度学习服务器租赁AutoDL

省钱绝招 #AutoDL #GPU #租显卡...

excel常用技能

1.基础技能 1.1 下拉框设置 a. 选中需要设置的列或单元格&#xff0c;数据 ---》 数据验证 b.验证条件 ---> 序列&#xff08;多个值逗号隔开&#xff09; 1.2 进度条百分比显示设置 开始 ---> 条件格式 --->新建规则--->编辑规则 1.3 相对引用和绝对引用…...

Mac电脑中隐藏文件(即以 . 开头的文件/文件夹)的显示和隐藏的两种方法

方法一&#xff1a;使用电脑快捷键&#xff0c;步骤如下&#xff1a; 1、点击一下桌面&#xff0c;用来激活 Finder &#xff1b; 2、同时按下 Command Shift 点&#xff0c;即 【Command Shift . 】&#xff1b; 3、 打开可能包含此类文件的文件夹&#xff0c;比如磁盘…...

【Linux】:进程信号(信号概念 信号处理 信号产生)

✨ 眼里有诗&#xff0c;自向远方 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;Linux—登神长阶 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#…...

Flink运行时架构以及核心概念

1.运行构架 1.提交作业后启动一个客户端进程&#xff0c;客户端解析参数&#xff08;-d -t 等等&#xff09;&#xff0c;后进行封装由Actor通信系统提交&#xff0c;取消&#xff0c;更新任务给JobManager。 2.JobManager&#xff08;进程&#xff09;通信系统一个组件叫分发…...

用 Python 从零开始创建神经网络(五):损失函数(Loss Functions)计算网络误差

用损失函数&#xff08;Loss Functions&#xff09;计算网络误差 引言1. 分类交叉熵损失&#xff08;Categorical Cross-Entropy Loss&#xff09;2. 分类交叉熵损失类&#xff08;The Categorical Cross-Entropy Loss Class&#xff09;展示到目前为止的所有代码3. 准确率计算…...

[CKS] K8S RuntimeClass SetUp

最近准备花一周的时间准备CKS考试&#xff0c;在准备考试中发现有一个题目关于RuntimeClass创建和挂载的题目。 ​ 专栏其他文章: [CKS] Create/Read/Mount a Secret in K8S-CSDN博客[CKS] Audit Log Policy-CSDN博客 -[CKS] 利用falco进行容器日志捕捉和安全监控-CSDN博客[CKS…...

【Python爬虫实战】轻量级爬虫利器:DrissionPage之SessionPage与WebPage模块详解

&#x1f308;个人主页&#xff1a;易辰君-CSDN博客 &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html ​ 目录 前言 一、SessionPage &#xff08;一&#xff09;SessionPage 模块的基本功能 &#xff08;二&#xff09;基本使…...

计算机网络-2.1物理层

文章目录 通信的基础概念信源、信宿、信号、信道码元、速率、波特带宽&#xff08;Hz&#xff09; 奈奎斯特采样定律和香农采样定律编码&解码&#xff0c;调制&解调常用的编码方法常用的调制方法 传输介质1. 导向型传输介质2. 非导向型传输介质物理层接口的特性 物理层…...

概述侧边导航的作用与价值

侧边导航的作用与价值&#xff1a;介绍侧边导航的核心优势和用户体验提升点。设计原则&#xff1a;使用表格对比说明侧边导航的三大设计准则。基础实现方法&#xff1a;分步骤讲解静态侧边导航的实现技术。高级交互实现&#xff1a;提供滑动式侧边栏的完整交互解决方案。优化技…...

jenkins gerrit-trigger插件配置

插件gerrit-trigger下载好之后要在Manage Jenkins -->Gerrit Trigger-->New Server 中新增Gerrit Servers 配置好保存后点击“状态”查看是否正常...

青少年编程与数学 01-011 系统软件简介 02 UNIX操作系统

青少年编程与数学 01-011 系统软件简介 02 UNIX操作系统 一、UNIX的历史沿革二、UNIX系统架构三、UNIX主要特性四、UNIX分支与变种五、UNIX设计哲学六、UNIX的影响与遗产 **摘要&#xff1a;**UNIX操作系统是现代计算领域最具影响力的操作系统之一&#xff0c;其设计哲学和技术…...

hadoop集群datanode启动显示init failed,不能解析hostname

三个datanode集群&#xff0c;有一个总是起不起来。去查看log显示 Initialization failed for Block pool BP-1920852191-192.168.115.154-1749093939738 (Datanode Uuid 89d9df36-1c01-4f22-9905-517fee205a8e) service to node154/192.168.115.154:8020 Datanode denied com…...

Nuxt.js 布局系统详解:构建可复用页面框架

Nuxt.js 是一个基于 Vue.js 的强大框架&#xff0c;旨在简化开发流程并提高项目的可维护性。布局系统是 Nuxt.js 项目结构中的一个重要组成部分&#xff0c;它位于 layouts 目录下&#xff0c;帮助开发者实现页面间的统一风格和结构复用。 什么是 Nuxt.js 布局系统 Nuxt.js 提…...

【EasyExcel】导出时添加页眉页脚

一、需求 使用 EasyExcel 导出时添加页眉页脚 二、添加页眉页脚的方法 通过配置WriteSheet或WriteTable对象来添加页眉和页脚。以下是具体实现步骤&#xff1a; 1. 创建自定义页眉页脚实现类 public class CustomFooterHandler implements SheetWriteHandler {private final…...

PyTorch 中cumprod函数计算张量沿指定维度的累积乘积详解和代码示例

torch.cumprod 是 PyTorch 中用于 计算张量沿指定维度的累积乘积&#xff08;cumulative product&#xff09; 的函数。 1、函数原型 torch.cumprod(input, dim, *, dtypeNone, outNone) → Tensor参数说明&#xff1a; 参数说明input输入张量dim累积乘积的维度dtype可选&…...

JavaScript 本地存储 (localStorage) 完全指南

文章目录 JavaScript 本地存储 (localStorage) 完全指南 &#x1f510;一、什么是 localStorage&#xff1f;&#x1f4a1;二、如何使用 localStorage&#xff1f;&#x1f527;1. 存储数据2. 读取数据3. 删除数据4. 清空所有数据 三、存储对象和数组的技巧 &#x1f3a8;1. 存…...

springCloud2025+springBoot3.5.0+Nacos集成redis从nacos拉配置起服务

文章目录 前言一、网关gateway选型1. 响应式编程模型2. 网关的特定需求3. 技术栈一致性4. 性能对比5. 实际应用场景优势 二、redis的集成1.引入库2.配置类A、自定义配置类RedisAfterNacosAutoConfigurationB、自定义配置类RedisConfig 总结 前言 最近在搭建最新的springCloud …...

人工智能--AI换脸

本文实现了一个简易的人脸交换程序&#xff0c;主要功能包括&#xff1a;1)检查所需的模型文件是否存在&#xff1b;2)使用预训练的Caffe模型检测图像中的人脸&#xff1b;3)将源图像的人脸区域通过泊松融合无缝地替换到目标图像上。程序通过OpenCV的DNN模块加载人脸检测模型&a…...