【LeetCode热题100】148. 排序链表(链表)

news/2024/7/5 3:57:35

一.题目要求

给你链表的头结点 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* slow = head;
        ListNode* fast = head->next;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
        }

        ListNode* mid = slow->next;
        slow->next = nullptr;  // 分割链表

        // 递归排序左右两部分
        ListNode* left = sortList(head);
        ListNode* right = sortList(mid);

        // 合并排序后的链表
        return merge(left, right);
    }

private:
    ListNode* merge(ListNode* l1, ListNode* l2) {
        ListNode dummy(0);
        ListNode* tail = &dummy;
        while (l1 && l2) {
            if (l1->val < l2->val) {
                tail->next = l1;
                l1 = l1->next;
            } else {
                tail->next = l2;
                l2 = l2->next;
            }
            tail = tail->next;
        }
        tail->next = l1 ? l1 : l2;
        return dummy.next;
    }
};


六.题目总结

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

递归分析:

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        // 退出条件
        if (!head || !head->next) return head;

        // 该层做的操作 即分割左右
        ListNode* slow = head;
        ListNode* fast = head->next;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
        }

        ListNode* mid = slow->next;
        slow->next = nullptr;  // 分割链表

        // 传给下一层继续分割
        //直到分割到不能再分开始合并
        ListNode* left = sortList(head);
        ListNode* right = sortList(mid);

        // 合并排序后的链表
        return merge(left, right);
    }

http://lihuaxi.xjx100.cn/news/2100987.html

相关文章

Winform编程详解六:RadioButton 单选框

一、属性介绍 1. (Name) 控件的对象标识符ID 2. BackColor 控件的背景颜色 3. Checked 控件的选中状态 4. Cursor 鼠标移过该控件显示的光标样式 5. Font 控件的字体样式 6. ForeColor 控件的文本颜色 7. Text 控件的文本 8. TextAlign 控件文本的对齐方式…

吴恩达prompt 笔记2:迭代提示开发(Iterative Prompt Develelopment)

1 前言 我们很难在初次尝试中就设计出最佳的提示&#xff0c;因此需要根据ChatGPT的反馈进行分析&#xff0c;分析输出具体在哪里不符合期望&#xff0c;然后不断思考和优化提示。如果有条件的话&#xff0c;最好是利用批量的样本来改善提示&#xff0c;这样可以对你的优化结…

数据库表结构导出工具【人生的第一个开源工具】

数据库表结构导出工具 如今我努力奔跑&#xff0c;不过是为了追上那个曾经被寄予厚望的自己 —— 约翰。利文斯顿 本工具是一个用于将数据库表结构导出到 Word 文档的实用工具。它能够连接到指定的数据库&#xff0c;提取数据库中所有表的结构信息&#xff0c;并将这些信息以专…

Linux之shell文本搜索工具grep

华子目录 文本搜索工具grep作用格式参数注意示例 正则表达式概念基本正则表达式常见元字符posix字符类示例 扩展正则表达式概念元字符示例三种支持扩展正则的方法 文本搜索工具grep 作用 grep是linux中一种强大的文件搜索过滤工具&#xff0c;可以按照正则表达式检索文件内容…

UG NX二次开发(C++)-CAM-获取加工操作的四种方法

文章目录 1、前言2、采用选中工序导航器获取操作的Tag_t3、采用遍历对象的方法获取操作的Tag_t4、采用Collection遍历获取操作对象NXOpen::CAM::Operation5、采用FindObject获取操作对象NXOpen::CAM::Operation6、以上4种方法封装成类 Class CAMOperation6.1 CAMOperation.h文件…

用pako.js压缩字符串,如何在后端用java解开?

背景&#xff1a;项目链路为腾讯clb->Ingress(nginx)->项目服务,腾讯的Ingress对header请求头最大值为256K&#xff0c;无法加大&#xff0c;由于业务配置数据增加&#xff0c;此问题诟病已久&#xff0c;于是想着压缩打请求头数据后再请求&#xff0c;从而解决请求头大的…

一套为中小电商企业构建的、开源的、简单实用的ERP系统需要接入的电商API接口以及实现的功能模块分析

一、项目简介 电商ERP系统为中小电商企业构建的一套简单实用的电商系统&#xff0c;本项目采用Java SpringBootVue2前后端分离开发。 支持供应商一件代发和仓库发货两种发货方式&#xff0c;主体流程覆盖采购、网店订单处理、供应商一件代发、仓库发货、网店售后、仓库出入库、…

[C++] 实现Union

前几天学了replacement new写的小玩意 #include <iostream> #include <functional> #include <string>// 可能因为const char*类型的缘故 // 用const ArgsT&&...会报错// 测试用类 struct Test {Test(){std::cout << "constructed"…