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

【LeetCode热题100】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 = []
输出:[]

四.解题思路

解法1:用map按值大小存结点
解法2:归并排序(GPT)

五.代码实现

解1

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        ListNode* dummy = new ListNode(0);
        map<int,vector<ListNode*>> nodeMap;
        while(head)
        {
            nodeMap[head->val].push_back(head);
            head = head->next;
        }
        ListNode* p = dummy;
        for(auto node : nodeMap)
        {
            for(vector<ListNode*>::iterator it = node.second.begin(); it != node.second.end(); it++)
                {
                    (*it)->next = nullptr;
                    p->next = *it;
                    p = p->next;
                }
        }
        return dummy->next;
    }
};

解2

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if (!head || !head->next) return head;

        ListNode* mid = getMid(head);
        ListNode* left = sortList(head);
        ListNode* right = sortList(mid);

        return merge(left, right);
    }

private:
    ListNode* getMid(ListNode* head) {
        ListNode* midPrev = nullptr;
        while (head && head->next) {
            midPrev = (midPrev == nullptr) ? head : midPrev->next;
            head = head->next->next;
        }
        ListNode* mid = midPrev->next;
        midPrev->next = nullptr; // 断开链表
        return mid;
    }

    ListNode* merge(ListNode* list1, ListNode* list2) {
        ListNode dummy(0);
        ListNode* ptr = &dummy;
        while (list1 && list2) {
            if (list1->val < list2->val) {
                ptr->next = list1;
                list1 = list1->next;
            } else {
                ptr->next = list2;
                list2 = list2->next;
            }
            ptr = ptr->next;
        }
        ptr->next = (list1) ? list1 : list2;
        return dummy.next;
    }
};

六.题目总结

归并排序在链表排序中非常有效,因为它可以利用链表的节点指针操作,无需像数组那样进行大量的元素交换,其时间复杂度是 O ( n l o g n ) O(nlogn) O(nlogn),但通常比基于 std::map 的方法更快,因为它具有更好的常数因子和较低的内存使用。

递归分析:

在这里插入代码片

相关文章:

  • 门牌制作-蓝桥杯?-Lua 中文代码解题第3题
  • 第八阶段:uni-app小程序 --首页开发(2)
  • 【深度学习目标检测】二十三、基于深度学习的行人检测计数系统-含数据集、GUI和源码(python,yolov8)
  • Spring同时集成JPA与Mybatis
  • 【C++】vector的使用及其模拟实现
  • SpringCloud Gateway 新一代网关
  • 引领人工智能时代的应用安全
  • java售后服务管理系统
  • Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)
  • 【leetcode热题】 两数之和 II - 输入有序数组
  • 9.用FFmpeg测试H.264文件的解码时间
  • 路由器端口转发远程桌面控制:一电脑连接不同局域网的另一电脑
  • springcloud五大组件:Eureka:注册中心、Zuul:服务网关、Ribbon:负载均衡、Feign:服务调用、Hystix:熔断器
  • tomcat 实现会话绑定
  • MATLAB中的数据类型,例如double,char,logical等。
  • 【MatLab】之:Simulink安装
  • uniapp-vue3 项目初始化集成配置【开箱即用】
  • 16. UE5 RPG获取GE应用的回调,并根据Tag设置数据显示到窗口
  • 工欲善其事,必先利其器,Markdown和Mermaid的梦幻联动(2)
  • 十三、软考-系统架构设计师笔记-层次式架构设计理论与实践
  • 夜读丨取稿费的乐趣
  • 盖茨说对中国技术封锁起到反作用
  • “无锡景・江南韵”:中国评弹艺术在尼日利亚收获众多粉丝
  • A股高开高走:沪指涨0.82%,创指涨2.63%,超4100股收涨
  • 文学花边|对话《借命而生》原著作者石一枫:我给剧打90分
  • 上汽享道出行完成13亿元C轮融资,已启动港股IPO计划