题目描述

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

解题思路

本题其实是让用归并排序的思想对链表进行排序,分为两个阶段:首先将整个链表分为两部分,一般是从中间切开,对两部分分别进行排序;然后将两个排序好的链表合并成一个链表。下面分别对两步进行分析:

  1. 将链表分为两部分时,要首先找到中间节点,考虑用快慢指针的方法,快指针每次走两步,慢指针每次走一步,这样当快指针无路可走即下两步出现空指针时,慢指针正好处于链表中间节点。然后从慢指针后把整个链表切成两半,两部分再分别进行递归排序
  2. 将两个排序链表合并时,首先初始化一个伪头节点,用其next指针指向新链表的头节点。从两个排序链表的头节点开始比较,每次将值较小的节点拼接到新链表后,若遇到其中一个节点为空则将另一个链表拼接到新链表后,这样遍历到两个链表末尾,最后返回伪头节点的next指针

代码

 /**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(head == NULL || head->next == NULL)
return head;
ListNode *quick = head, *slow = head;
//快慢指针找到中间节点
while(quick->next && quick->next->next){
quick = quick->next->next;
slow = slow->next;
}
quick = slow;
slow = slow->next;
quick->next = NULL;
ListNode *first = sortList(head);
ListNode *second = sortList(slow);
return mergeList(first, second);
}
ListNode* mergeList(ListNode* first, ListNode* second){
ListNode node(-);
ListNode *p = &node;
while(first != NULL || second != NULL){
int val1 = first == NULL ? INT_MAX : first->val;
int val2 = second == NULL ? INT_MAX : second->val;
if(val1 < val2){
p->next = first;
first = first->next;
}
else{
p->next = second;
second = second->next;
}
p = p->next;
}
return node.next;
}
};

最新文章

  1. Java学习之LinkedHashMap学习总结
  2. .NET Remoting 应用实例
  3. 用linq批量更新数据集
  4. 常见面试题之ListView的复用及如何优化
  5. Timer中schedule()的用法
  6. poj----1330Nearest Common Ancestors(简单LCA)
  7. linux中less命令使用
  8. Matlab编程实例(2) 同期平均
  9. 搭建自己的SIPserver:开源sipserveropensips的搭建及终端TwInkle的使用
  10. synchronized细节问题
  11. DDD理论学习系列(7)-- 值对象
  12. node.js与比特币(typescript实现)
  13. spring mvc跨域(post)--filter方案
  14. python模块之os_sys_动态导入_包
  15. 使用layer弹出Ueditor实现父子传值
  16. Linux-GLIBCXX版本过低导致编译错误--version `GLIBCXX_3.4.20&#39; not found
  17. Goroutines
  18. JFrame,JPanel,JLabel详解
  19. Winzip和Winrar命令行的使用
  20. css position说明

热门文章

  1. 同步(Synchronous)和异步(Asynchronous)方法的区别
  2. 微信小程序wx.showActionSheet调用客服信息功能
  3. vue项目中使用mockjs+axios模拟后台数据返回
  4. 给Tomcat打开远程debug端口
  5. python爬虫练习之批量下载zabbix文档
  6. 排序——插入排序(C语言)
  7. 个人总结的J2EE目前知道的涵盖面,从大方向入手,多写单元测试,加强基础
  8. cmd拷贝文件夹时,处理提示
  9. 标准C语言(5)
  10. CI/CD----jenkins+gitlab+django(内网)