题目

在 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个和1个合并,再2个和2个
自底向上省去了划分的过程(实际上没起任何作用),直接开始合并
具体实现时将整体链表一段一段的切开,每两个调用一次合并链表的merge函数

代码

  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. * int val;
  5. * ListNode *next;
  6. * ListNode(int x) : val(x), next(NULL) {}
  7. * };
  8. */
  9. class Solution {
  10. public:
  11. ListNode* sortList(ListNode* head) {
  12. ListNode* dummyHead = new ListNode(-1);
  13. dummyHead->next = head;
  14. int sz = 1;
  15. while(true){
  16. ListNode *pre = dummyHead, *cur = pre;
  17. while(cur->next){
  18. cur = pre;
  19. for(int i = 0; i < sz && cur->next; i ++, cur = cur->next);
  20. if(cur->next){
  21. ListNode* pre2 = cur;
  22. for(int i = 0; i < sz && cur->next; i ++, cur = cur->next);
  23. ListNode* next = cur->next, *head2 = pre2->next;
  24. pre2->next = NULL, cur->next = NULL;
  25. ListNode* tail;
  26. pre->next = merge(pre->next, head2, tail);
  27. pre = tail;
  28. pre->next = next;
  29. }
  30. else if(pre == dummyHead){
  31. sz = 0;
  32. break;
  33. }
  34. }
  35. if(sz == 0 || cur == dummyHead) break;
  36. else sz *= 2;
  37. }
  38. ListNode* ret = dummyHead->next;
  39. delete dummyHead;
  40. return ret;
  41. }
  42. private:
  43. ListNode* merge(ListNode* a, ListNode* b, ListNode* &tail){
  44. ListNode* dummyHead = new ListNode(-1);
  45. ListNode *p1 = a, *p2 = b, *p = dummyHead;
  46. while(p1 && p2)
  47. if(p1->val < p2->val){
  48. p->next = p1;
  49. p1 = p1->next;
  50. p = p->next;
  51. p->next = NULL;
  52. }
  53. else{
  54. p->next = p2;
  55. p2 = p2->next;
  56. p = p->next;
  57. p->next = NULL;
  58. }
  59. if(p1) p->next = p1;
  60. if(p2) p->next = p2;
  61. tail = p;
  62. while(tail->next) tail = tail->next;
  63. ListNode* ret = dummyHead->next;
  64. delete dummyHead;
  65. return ret;
  66. }
  67. };