LeetCode 148——排序链表
1. 题目

2. 解答
2.1 快速排序
可参考 快速排序和归并排序 中的第一种快速排序思想,与在数组中排序有两点不同。
第一,我们需要取最后一个元素作为主元,在数组中可以直接访问到最后一个元素,但在单链表中,我们需要先遍历一遍链表才能访问到最后一个元素。
第二,在数组中,利用主元将数组划分为左右两个部分后,我们可以用下标来递归调用,但在链表中,我们改用头指针和尾指针来标识左右两个部分。如下图所示,左半部分头指针为 head,尾指针为 p1;右半部分头指针为 p1-next,尾指针为 end。

class Solution {
public:
ListNode* sortList(ListNode* head) {
if(head == NULL) return head;
Quick_Sort(head, NULL);
return head;
}
void Quick_Sort(ListNode* head, ListNode* end)
{
if (head != end && head->next != end)
{
ListNode* ptr = head;
while(ptr->next != end) ptr = ptr->next; // 取链表最后一个元素作为主元
int pivot = ptr->val;
ListNode* p1 = head;
ListNode* p2 = head;
while(p2->next != end)
{
if(p2->val < pivot)
{
int temp = p2->val;
p2->val = p1->val;
p1->val = temp;
p1 = p1->next;
}
p2 = p2->next;
}
p2->val = p1->val;
p1->val = pivot;
Quick_Sort(head, p1); // 此时 p1 指向 pivot,前一半链表头为 head,尾为 p1
Quick_Sort(p1->next, end); // 后一半链表头为 p1->next,尾为 end
}
}
2.2 归并排序
可参考 快速排序和归并排序 中的归并排序思想,主要有三个步骤。
- 找到链表的中间结点
- 递归对左半部分和右半部分排序
- 合并排序好的两部分链表,这部分因为不能使用额外空间,我们就将一个链表插入到另一个链表中去
class Solution {
public:
ListNode* sortList(ListNode* head) {
return Merge_Sort(head);
}
ListNode* Merge_Sort(ListNode* head)
{
ListNode * mid = Find_Mid(head);
if (mid)
{
ListNode* right_head = mid->next;
mid->next = NULL;
ListNode* left_head = Merge_Sort(head);
right_head = Merge_Sort(right_head);
head = Merge_List(left_head, right_head);
}
return head;
}
ListNode* Merge_List(ListNode* left_head, ListNode* right_head)
{
ListNode* l1 = left_head;
ListNode* l2 = right_head;
if (left_head->val > right_head->val)
{
l1 = right_head;
l2 = left_head;
}
// l1 指向第一个节点值较小的链表,然后将 l2 中的每个节点插入到 l1 中
ListNode* p1 = NULL;
ListNode* head = l1;
while (l1->next && l2)
{
if (l1->next->val > l2->val)
{
p1 = l1->next;
l1->next = l2;
l2 = l2->next;
l1 = l1->next;
l1->next = p1;
}
else
{
l1 = l1->next;
}
}
if (l2) l1->next = l2; //若 l2 还有节点直接插入到 l1 后面即可
return head;
}
ListNode* Find_Mid(ListNode* head)
{
if (head == NULL || head->next == NULL) return NULL;
ListNode* slow = head;
ListNode* fast = head;
while (fast->next != NULL && fast->next->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
};
获取更多精彩,请关注「seniusen」!

LeetCode 148——排序链表的更多相关文章
- [LeetCode] 148. 排序链表 ☆☆☆(归并排序)
148.排序链表 描述 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3输出: 1->2->3-> ...
- Java实现 LeetCode 148 排序链表
148. 排序链表 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3 输出: 1->2->3-> ...
- LeetCode 148. 排序链表(Sort List)
题目描述 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示例 ...
- [Leetcode]148. 排序链表(归并排序)
题目 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示例 2: ...
- LeetCode 148 排序链表
题目: 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示例 2 ...
- leetcode 148. 排序链表(c++)
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3输出: 1->2->3->4示例 2: 输入: ...
- leetcode 148排序链表
优先队列容器,使用小顶堆排序:timeO(nlogn) spaceO(n) /** * Definition for singly-linked list. * struct ListNode { * ...
- C#LeetCode刷题-链表
链表篇 # 题名 刷题 通过率 难度 2 两数相加 29.0% 中等 19 删除链表的倒数第N个节点 29.4% 中等 21 合并两个有序链表 C#LeetCode刷题之#21-合并两个有序链 ...
- LeetCode刷题 链表专题
链表专题 链表题目的一般做法 单链表的结构类型 删除节点 方法一 方法二 增加节点 LeedCode实战 LC19.删除链表的倒数第N个结点 解法思路 LC24.两两交换链表中的节点 解法思路 LC6 ...
随机推荐
- freemark生成静态网页乱码问题
输出流问题:修改Writer如下: OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(dir), &quo ...
- ./redis-trib.rb [ERR] Sorry, can't connect to node 192.168.*.*
原因在于在redis.conf中绑定了127.0.0.1 改为自己虚拟机地址.重新启动
- The number of sections contained in the collection view after the update (1) must be equal to the number of sections contained in the collection view before the update (0), plus or minus the number of
现象:当删除CollectionView 当中的某个section的时候,报上面的错误 初步分析:当前CollectionView删除前后都不止一个Section,怎么会报那样的错误:猜想可能是相册界 ...
- vdbench 数据校验测试方法
[root@dntosu001 vdbench]# cat pbd.conf*SD: Storage Definition*WD: Workload Definition*RD: Run Defini ...
- vim插件管理 - vim-plug
vim-plug是一款轻量的vim插件管理工具. GitHub:https://github.com/junegunn/vim-plug 插件的安装 unix curl -fLo ~/.vim/aut ...
- IntelliJ IDEA(2018)安装和破解。
一.下载并安装, IntelliJ IDEA的官网:https://www.jetbrains.com 二.破解. 百度下载一个 JetbrainsCrack-2.6.2.jar ...
- 我的 Delphi 学习之路 —— Delphi 的安装
标题:我的 Delphi 学习之路 -- Delphi 的安装 作者:断桥烟雨旧人伤 1. Delphi 版本的选择 Delphi 版本众多,我该选择哪一个,这确实是个问题,自从 Borland 公司 ...
- MySQL用户账户管理/权限管理/资源限制
MySQL 的权限表在数据库启动的时候就载入内存,当用户通过身份认证后,就在内存中进行相应权限的存取,这样,此用户就可以在数据库中做权限范围内的各种操作了. mysql 的权限体系大致分为5个层级: ...
- unix文件共享
UNIX系统支持在不同的进程间共享打开文件.内核使用3种数据结构表示打开文件,他们之间的关系决定了在文件共享方面一个进程对另一个进程产生的影响. (1)每个进程在进程表中都有一个记录项,记录项中包含一 ...
- PTA(Basic Level)-1076 Wifi密码
一 题目介绍: 现将 wifi 密码设置为下列数学题答案:A-1:B-2:C-3:D-4.本题就要求你写程序把一系列题目的答案按照卷子上给出的对应关系翻译成 wifi 的密码.这里简单假设每道 ...