leetcode 148. 排序链表 中等

news2024/12/26 23:14:15

给你链表的头结点 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/

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

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

相关文章

Elasticsearch中什么是倒排索引?

倒排索引&#xff08;Inverted Index&#xff09;是一种索引数据结构&#xff0c;它在信息检索系统中被广泛使用&#xff0c;特别是在全文搜索引擎中。倒排索引允许系统快速检索包含给定单词的文档列表。它是文档内容&#xff08;如文本&#xff09;与其存储位置之间的映射&…

excel-VLOOKUP函数使用/XVLOOKUP使用

多个窗口同时编辑表格&#xff0c;方便对照操作 使用开始-视图-新建窗口 将战区信息表的三列数据匹配到成交数据表上 可以使用VLOOKUP函数 有4个参数&#xff08;必须要查找的值&#xff0c; 要查找的区域&#xff0c;要返回区域的第几列数据&#xff0c;一个可选参数查找匹…

netcore 静态文件目录浏览

环境&#xff1a;Net6 string dirPath "C:\\Users\\15298\\Pictures"; var fileProvider new PhysicalFileProvider(dirPath); app.UseStaticFiles(new StaticFileOptions {FileProvider fileProvider,RequestPath new PathString(("/files")) }); // …

1Panel修改PostgreSQL时区

需求 1Panel安装的PostgreSQL默认是UTC时区&#xff0c;需要将它修改为上海时间 步骤 进入PostgreSQL的安装目录 /opt/1panel/apps/postgresql/postgresql/data打开postgresql.conf文件 修改&#xff1a; log_timezone Asia/Shanghai timezone Asia/Shanghai保存后重启…

函数式接口和stream

函数式接口&#xff08;Functional Interface&#xff09;是Java 8引入的一个新特性&#xff0c;它只有一个抽象方法的接口。这意味着你可以将一个函数式接口作为参数传递给方法&#xff0c;或者将其实现为一个lambda表达式。函数式接口的主要目的是允许你以声明性方式处理操作…

Oracle 高水位线和低-高水位线(High Water Mark Low High Water Mark)

在Oracle的逻辑存储结构中&#xff08;表空间-段-区-块&#xff09;&#xff0c;数据是存在数据段中的&#xff0c;通常一个表就是一个数据段&#xff0c;而段最终又由许多数据块组成。当数据存入数据块时&#xff0c;需要对块进行格式化&#xff0c;高水位线&#xff08;High …

科技资讯|Matter 1.4 标准正式发布,低功耗蓝牙助力其发展

连接标准联盟&#xff08;CSA&#xff09;宣布推出最新的 Matter 1.4 版本&#xff0c;引入了一系列新的设备类型和功能增强&#xff0c;有望提高包括 HomeKit 在内的智能家居生态系统之间的互操作性。 设备供应商和平台能够依靠增强的多管理员功能改善多生态系统下的用户体验&…

python练习-Django web入门

python -m pip install --user requests使用API调用请求数据 处理API响应 import requestsclass Requests:def request(self):url "https://www.toutiao.com/stream/widget/local_weather/data/?city北京"headers {"Accept": "application/json;…

元器件封装

元器件封装类型 为什么越来越多用贴片元件&#xff0c;而不是插件元件 为什么越来越多用贴片元件&#xff0c;而不是插件元件 1.体积小、质量小、容易保存和运输&#xff1b; 2.容易焊接和拆卸。抗震效果好。 贴片元件不用过孔&#xff0c;用锡少。直插元件最麻烦的就是拆卸&a…

[SaaS] 数禾科技 AIGC生成营销素材

https://zhuanlan.zhihu.com/p/923637935https://zhuanlan.zhihu.com/p/923637935

自顶向下逐步求精解决LeetCode第3307题找出第K个字符II题

3307.找出第K个字符II 难度&#xff1a;困难 问题描述&#xff1a; Alice和Bob正在玩一个游戏。最初&#xff0c;Alice有一个字符串word"a"。 给定一个正整数k和一个整数数组operations&#xff0c;其中operations[i]表示第i次操作的类型。 现在Bob将要求Alice按…

v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条

效果 导入组件 import ElImageViewer from "element-ui/packages/image/src/image-viewer"; components:{ ElImageViewer },模板使用组件 <el-image-viewerv-if"isShowPics":on-close"closeViewer":url-list"srcList"/>定义两…

Redis - 哨兵(Sentinel)

Redis 的主从复制模式下&#xff0c;⼀旦主节点由于故障不能提供服务&#xff0c;需要⼈⼯进⾏主从切换&#xff0c;同时⼤量 的客⼾端需要被通知切换到新的主节点上&#xff0c;对于上了⼀定规模的应⽤来说&#xff0c;这种⽅案是⽆法接受的&#xff0c; 于是Redis从2.8开始提…

使用wordpress搭建简易的信息查询系统

背景 当前有这样的一个需求&#xff0c;要实现让客户能够自助登录系统查询一些个人的信息&#xff0c;市面上没有特别符合我的需求的产品&#xff0c;经过一段时间的研究&#xff0c;想出了一个用wordpress实现简易信息查询系统&#xff0c;有两种方式。 方式一&#xff1a;使…

探索 Python HTTP 的瑞士军刀:Requests 库

文章目录 探索 Python HTTP 的瑞士军刀&#xff1a;Requests 库第一部分&#xff1a;背景介绍第二部分&#xff1a;Requests 库是什么&#xff1f;第三部分&#xff1a;如何安装 Requests 库&#xff1f;第四部分&#xff1a;Requests 库的基本函数使用方法第五部分&#xff1a…

【青牛科技】 GC6153——TMI8152 的不二之选,可应用于摇头机等产品中

在电子工程领域&#xff0c;不断寻求性能更优、成本更低的解决方案是工程师们的永恒追求。今天&#xff0c;我们要为广大电子工程师带来一款极具竞争力的产品 —— GC6153&#xff0c;它将成为 TMI8152 的完美替代之选。 一、产品背景 随着科技的飞速发展&#xff0c;电子设备…

基于yolov8、yolov5的番茄成熟度检测识别系统(含UI界面、训练好的模型、Python代码、数据集)

摘要&#xff1a;番茄成熟度检测在农业生产及质量控制中起着至关重要的作用&#xff0c;不仅能帮助农民及时采摘成熟的番茄&#xff0c;还为自动化农业监测提供了可靠的数据支撑。本文介绍了一款基于YOLOv8、YOLOv5等深度学习框架的番茄成熟度检测模型&#xff0c;该模型使用了…

艾体宝干货丨微突发流量检测与分析:IOTA让网络监控更精准

网络流量中的微突发问题常常难以察觉&#xff0c;但它们可能对网络性能产生显著影响。这篇文章深入探讨了如何利用IOTA来捕捉和分析微突发&#xff0c;帮助您快速有效地解决网络中的突发流量问题。 什么是微突发&#xff08;Microburst&#xff09;流量&#xff1f; 微突发是…

论文略读: ALPAGASUS: TRAINING A BETTER ALPACA WITH FEWER DATA

ICLR 2024 1 背景 大模型通常需要在有监督指令数据集上进行指令微调来加强指令遵循能力 但是广泛使用的数据集包含许多具有不正确或不相关响应的低质量样本&#xff0c;这对大模型微调具有误导性——>论文提出了一种简单有效的数据选择策略&#xff0c;使用ChatGPT自动识别…

【Android】ANR监控治理技术方案

一、 背景 1、 bugly针对crash监控做的比较好&#xff0c;但是对anr监控&#xff0c;早期版本监听 /data/anr 目录的变化可以拿到数据&#xff0c;但是现在高版本已经没有权限监听此目录&#xff0c;当前数据非常少&#xff0c;结合历次数据来看对我们解决ANR问题没有任何帮助…