HOT33-排序链表

news/2024/11/6 9:44:27/

    leetcode原题链接:排序链表

题目描述

      给你链表的头结点 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 = []
输出:[]

提示: 

  • 链表中节点的数目在范围 [0, 5 * 104] 内
  • -105 <= Node.val <= 105

进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

解题方法:类似数组的归并排序法。解题过程如下

1. 找到链表的中间节点。

2. 拆分链表,将原链表一分为二。

3. 分别对区间[head, mid]和[mid->next,tail]组成两个链表内部各自排序。

4. 将两个有序空间合并。

C++代码

#include <iostream>
#include <memory> //std::shared_ptr
/*** 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) {}*     1->2->3->4->5*.    1->2->3->4->5->6* };*/
class Solution {
public:ListNode* sortList(ListNode* head) {if (!head || !head->next) { //空链表或者链表仅包含一个节点return head;}//1. 找到链表的中间节点ListNode* p_mid = get_mid_node(head);if (!p_mid) {return nullptr;}//2. 拆分链表,将原链表一分为二ListNode *head1 = p_mid->next;//获取后半部分的head节点p_mid->next = nullptr;//拆分前半部分//3. 分别对区间[head, mid], [mid->next,tail]排序head = sortList(head);//对左半部分排序head1 = sortList(head1);//对右半部分排序//4. 将两个有序空间合并return merge(head, head1);//返回合并后的链表}// 快慢指针获取链表的中间节点ListNode* get_mid_node(ListNode* head) {if (!head || !head->next) {return head;}ListNode* p1 = head;//一次走1步的慢指针ListNode* p2 = head;//一次走2步的快指针while (p2 && p2->next && p2->next->next) {p1 = p1->next;p2 = p2->next->next;}return p1;}// 合并两个有序的链表ListNode* merge(ListNode* head1, ListNode* head2) {if (!head1) {return head2;}if (!head2) {return head1;}std::shared_ptr<ListNode> dummy_node(new ListNode(0));ListNode* p = dummy_node.get();//用哨兵节点可以避免对新链表头节点单独判断ListNode* p1 = head1;ListNode* p2 = head2;while (p1 && p2) {if (p1->val <= p2->val) {p->next = p1;p1 = p1->next;} else {p->next = p2;p2 = p2->next;}p = p->next;}if (p1) { //head1更长p->next = p1;}if (p2) { //head2更长p->next = p2;}return dummy_node->next;}
};


http://www.ppmy.cn/news/698663.html

相关文章

OPPO K9试水“捆绑销售”,消费者“赚了”还是“亏了”?

【原创】 号称“充电5分钟&#xff0c;开黑两小时”的OPPO新品K9于5月6日正式发布&#xff0c;这句“似曾相识”的OPPO“过气”广告语&#xff0c;又重新出现在了江湖&#xff0c;说是词穷也好&#xff0c;为了突出手机卖点也罢&#xff0c;反正新品是上了。 出了新品&#x…

天玑1200来了,2021年旗舰手机迎体验新趋势

旗舰手机芯片越来越追求5G式的极致体验了。1月20日&#xff0c;联发科发布了天玑1200&#xff0c;这款芯片定位于“天玑旗舰”&#xff0c;通过搭载更先进的5G和AI技术&#xff0c;在拍照、视频和游戏等多媒体场景下&#xff0c;能够为用户提供非同寻常的优秀使用体验。 天玑旗…

「2024」预备研究生mem-利润与利润率增长率问题

一、利润与利润率 二、增长率问题 易错题&#xff1a; 三、课后题

卸载及安装docker的教程-ubuntu

一、前言 万地高楼平地起~ 二、环境 OS&#xff1a;Ubuntu 20.04 64 bit 显卡&#xff1a;NVidia GTX 2080 Ti CUDA&#xff1a;11.2 三、卸载docker 1、删除docker及安装时自动安装的所有包 apt-get autoremove docker docker-ce docker-engine docker-ce-*for pkg in …

华硕笔记本安装ubuntu16.04

参考链接 https://blog.csdn.net/jacke121/article/details/79483400

华硕笔记本r414u怎么安装键盘_华硕笔记本怎么安装系统|华硕R414UV7200安装Win10专业版64位教程...

一、准备工作 1、将华硕R414UV7200笔记本重要文件进行备份&#xff1b; 2、准备8G或更大容量空U盘制作pe启动盘&#xff1a;二、BIOS修改与U盘启动 1、重启笔记本按esc进入BIOS设置&#xff0c;然后按F7进入高级模式&#xff0c;按→方向键移动到Security&#xff0c;选择Secur…

Ubuntu16.04 安装 NVIDIA 显卡驱动(亲测可用)

环境&#xff1a;Ubuntu 16.04&#xff0c;GeForce RTX 3080 安装NVIDIA 显卡驱动 如何检查系统的显卡型号 lspci -vnn | grep VGA -A 12得到结果中 NVIDIA Corporation Device 后的 ‘[]’ 里的十六进制码。在 http://pci-ids.ucw.cz/mods/PC/10de?actionhelp?helppci 中输…

【一文搞定】Ubuntu20.04系统安装显卡驱动和多个实用软件

显卡驱动安装&#xff1a; 方法1&#xff1a;可参见博客&#xff1a;https://blog.csdn.net/shenweikkx/article/details/93383225 注意&#xff1a;如果安装Ubuntu20.04系统时选择的Ubuntu&#xff08;safe graphic&#xff09;进行安装&#xff0c;那么&#xff0c;显卡驱动安…