上一篇文章用数组实现了二路归并排序,核心在于要对每次减半的元素进行实质性的改变,在数组中我们用临时数组记录每次merge的结果,在链表中用归并排序更加直接,因为我们操作的是结点的指针。

题目描述

难度:中等

Sort a linked list in O(n log n) time using constant space complexity.

Example 1:

Input: 4->2->1->3
Output: 1->2->3->4

Example 2:

Input: -1->5->3->4->0
Output: -1->0->3->4->5

题解

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {public:ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {ListNode* dummy = new ListNode(-1);ListNode* cur = dummy;while (l1 && l2) {if (l1->val < l2->val) {cur->next = l1;cur = l1;l1 = l1->next;} else {cur->next = l2;cur = l2;l2 = l2->next;   }}if (l1) {cur->next = l1;} if (l2) {cur->next = l2;}return dummy->next;}ListNode* sortList(ListNode* head) {// 归并排序,找到中间结点的方法是:快慢指针if (!head || !head->next) {return head;}ListNode* fast = head, *slow = head;// 奇数个元素时,slow结束时指向中间元素// 偶数个元素时,slow结束时指向前半段的最后一个元素,所以需要slow = slow->nextwhile (fast->next && fast->next->next) {fast = fast->next->next;slow = slow->next;}// 断开成两部分fast = slow;slow = slow->next;fast->next = nullptr;ListNode* l1 = sortList(head);ListNode* l2 = sortList(slow);return mergeTwoLists(l1, l2);   }
};

在数组中计算中间点的方法是直接用下标计算,如果能够解决链表中的这个问题,则归并排序就很自然了。

回想一下快慢指针的功效,让快指针比慢指针速度快一倍,那么等快指针都跑完了,则慢指针才跑一半。

链表本身的长度是有限的,所以这个方法很可行。

找到中间点以后,需要把链表打断,调用merge即可,关于递归,在前文讲了一些思考(https://blog.csdn.net/u011240016/article/details/87903240),这里不再赘述。

PS. 想起实现这段代码时更新cur = l1时位置放在了l1 = l1->next后面导致的空指针问题。对于指针问题,需要特别注意操作的顺序,一点点的顺序错位,都会导致完全不同的结果。

END.

【LeetCode 148】链表的归并排序相关推荐

  1. leetcode 148 --- 链表排序

    1 题目 链表排序 2 解法 2.1 冒泡排序 /*** struct ListNode {* int val;* struct ListNode *next;* };*/class Solution ...

  2. 链表排序---迭代版本归并算法 + [leetcode]148. 排序链表

    前言: 对于链表来说,排序首选应该是归并算法 维基百科上有归并算法的迭代版本和递归版本 基于数组实现的. https://zh.wikipedia.org/wiki/%E5%BD%92%E5%B9%B ...

  3. 每周leetcode - 02链表专题 237/83/234/138/92/142/Offer 22/148/23/24/147/86/61/328/2/Offer06

    文章目录 leetcode - 237. 删除链表中的节点 leetcode - 83. 删除排序链表中的重复元素 leetcode - 234. 回文链表 leetcode - 138. 复制带随机 ...

  4. 【编程4】插入排序+快速排序+LeetCode.148(排序链表)

    文章目录 一.排序链表 1.题目描述--LeetCode.148 2.分析 (1)一般的快排 (2)解题思路 3.实现 二.排序算法 三.插入排序 1.基本思想 (1)过程概述 (2)具体算法描述: ...

  5. 【归并排序+递归】LeetCode 148. Sort List

    LeetCode 148. Sort List Solution1:我的答案 很多递归 /*** Definition for singly-linked list.* struct ListNode ...

  6. Leetcode 148. 排序链表 解题思路及C++实现

    解题思路: 对链表进行归并排序,使用 fast 和 slow 两个指针,遍历一次链表,就能将链表切分为两半,然后使用归并排序的方法. /*** Definition for singly-linked ...

  7. leetcode:Sort List(一个链表的归并排序)

    Sort a linked list in O(n log n) time using constant space complexity. 分析:题目要求时间复杂度为O(nlogn),所以不能用qu ...

  8. LeetCode 148. Sort List--面试算法题--C++,Python解法

    LeetCode 148. Sort List–面试算法题–C++,Python解法 LeetCode题解专栏:LeetCode题解 LeetCode 所有题目总结:LeetCode 所有题目总结 大 ...

  9. 单链表的归并排序(C语言)

    //数据域val,指针域nextstruct ListNode{int val;struct ListNode* next; }; //创建单链表struct ListNode* CreatList( ...

最新文章

  1. Java事务处理类(源码)
  2. Leetcode 313. 超级丑数 解题思路及C++实现
  3. DM达梦数据库 - 设置忽略关键字方法,login关键字处理实例演示
  4. Ardino基础教程 8_模拟值
  5. 探讨磷酸铁锂电池在UPS的应用
  6. mysql的varchar最大值是多少_MySQL varchar计算:求列的数额和计算N的最大值
  7. Mybatis逆向生成报错:文档根元素 “project“ 必须匹配 DOCTYPE 根 “null“。
  8. OA应用分析:机电企业如何选型OA系统
  9. 安卓前端布局Android,Android开发的几种常见布局
  10. ear的英语怎么念_ear英语怎么读
  11. ARMS在APM工具选型中的实践
  12. 2020智慧零售行业研究报告
  13. html5圆圈刷新 博客,html5话出带圆的波浪线
  14. CentOS下通过yum安装svn及配置
  15. php不使用copy()函数复制文件的方法
  16. R语言t检验,秩和检验,fdr的案例分析
  17. JavaScript实现输出100以内含7和7倍数所有数
  18. C#中的特性,什么是特性.
  19. 一个技术人员的MacOS下环境装备
  20. Chrome安装插件提示 出现错误 image decode failed

热门文章

  1. 相机标定(三)—— 正交投影和透视投影变换
  2. 数据结构笔记(三十五)--排序概念
  3. php cannot bind port to socket,PHP基于socket实现客户端和服务端通讯功能
  4. python函数定义语法_python 函数基础 定义
  5. html div右下浮动,div 初始化及左右浮动
  6. linux下两个线程交替打印,两个线程交替打印AB
  7. android多申请内存,Android内存等信息
  8. 555定时器回差电压计算公式_555定时器及其应用
  9. video safari不支持吗_您支持吗? 公园遛狗纳入 “不文明行为黑名单”
  10. linux搜索命令有哪些,linux五大搜索命令学习