这道题的难点在于:

1. 对链表排序,这样就不能向访问数组一样随机访问里头的元素;

2. 题中要求时间复杂度为O(nlogn),且空间复杂度为O(1)

我们一般了解的是快排和归并可以达到这样的时间复杂度,但是快排对于链表操作显得比较复杂(其实归并对这个链表操作也很复杂),而通常的归并的空间复杂度又是O(n)。

后来看了有原地归并排序,其空间复杂度达到O(1),我使用inplace-bottom-Up Merge sort。程序调试了很久(中间有过放弃的念头,每次这个念头出现的时候,我就对自己说,说不定这个bug解决了程序就AC了,终于在最后的期待中看到了AC),主要是因为链表的操作和Java中一般的赋值是浅copy。

bottom-up merge sort 可参见:http://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation

inplace merge sort 参考的是:http://www.cnblogs.com/daniagger/archive/2012/07/25/2608373.html

下面是AC代码:

  1     /**
  2      * 总入口
  3      * @param head
  4      * @return
  5      */
  6     public ListNode sortList(ListNode head) {
  7         ListNode pointer = head;
  8         int len = 0;
  9         if(head == null || head.next == null)
 10             return head;
 11         while(pointer!=null)
 12         {
 13             len++;
 14             pointer = pointer.next;
 15         }
 16         return sort(head, len);
 17     }
 18     /**
 19      * 进入自底向上归并排序
 20      * @param head
 21      * @param len
 22      * @return
 23      */
 24     private ListNode sort(ListNode head,int len)
 25     {
 26         int width = 1;
 27         ListNode r = null;
 28         for(width = 1;width<=len;width = 2*width)
 29         {
 30             ListNode left = head;
 31             ListNode pLeft = null;
 32             ListNode pmid = left, mid=left.next, end = null, endNext = null;
 33             int cnt = 0;
 34             for(left = head;left!=null;left =endNext)
 35             {
 36                 pmid = left;
 37                 cnt = 0;
 38                 while(++cnt<width && pmid.next!=null)
 39                 {
 40                     pmid = pmid.next;
 41                 }
 42                 mid = pmid.next;//if pmid.next == null 则没有左子数组
 43                 if(mid == null)
 44                     break;
 45                 end = mid;
 46                 cnt = 0;
 47                 while(++cnt<width && end.next!=null)
 48                 {
 49                     end = end.next;
 50                 }
 51                 endNext = end.next;
 52                 ListNode l = bottomUpSort(pLeft,left,pmid,mid,end,endNext);
 53                 if(end.next!=endNext)
 54                     end = pmid;
 55                 if(l!=null)
 56                 {
 57                     r = l;
 58                     head = r;
 59                 }
 60                 pLeft = end;
 61             }
 62         }
 63         if(r == null)
 64             return head;
 65         return r;
 66     }
 67     /**
 68      * bottomUpSort 这个名字应该改成inPlaceSort更恰当
 69      * @param pLeft left的前一个node指针,为null表示left为链表头
 70      * @param left 当前左子数组的第一个指针
 71      * @param pmid 当前左子数组的最后一个指针
 72      * @param mid 当前右子数组的第一个指针
 73      * @param end 当前有子数组的最后一个指针
 74      * @param endNext end的next Node
 75      */
 76     private ListNode bottomUpSort(ListNode pLeft, ListNode left, ListNode pmid, ListNode mid, ListNode end, ListNode endNext)
 77     {
 78         ListNode p1 = left, pp1 = pLeft ;
 79         ListNode p2 = mid, pp2 = pmid ;
 80         ListNode t = null;
 81         //pp1 = (left.val <= mid.val) ? left: null;
 82         while(p1!=p2 && p2!=endNext )
 83         {
 84             while(p1!=pmid.next && p1.val<=p2.val )
 85             {
 86                 pp1 = p1;
 87                 p1 = p1.next;
 88             }
 89             if(p1 == mid)
 90                 break;
 91             while(p2!= endNext && p2.val<=p1.val )
 92             {
 93                 pp2 = p2;
 94                 p2 = p2.next;
 95             }
 96             ListNode ln = exchange(pp1,p1,pp2,p2,pmid,mid);
 97             if(ln != null)
 98                 t = ln;
 99             //end = pmid;
100             mid = pmid.next;
101         }
102         end = pmid;
103         if(pLeft == null)
104             return t;
105         return null;
106     }
107     /**
108      * 把小的部分移到前面  之所以参数比较多,是为了链表更便捷的操作
109      * @param pp1
110      * @param p1
111      * @param pp2
112      * @param p2
113      * @param pmid
114      * @param mid
115      * @return
116      */
117     private ListNode exchange( ListNode pp1,ListNode p1, ListNode pp2,ListNode p2, ListNode pmid, ListNode mid)
118     {
119         if(pp1 == null)
120         {
121             pp2.next = p1;
122             pmid.next = p2;
123             return mid;
124         }
125         pp1.next = mid;
126         pp2.next = p1;
127         pmid.next = p2;
128         return null;
129     }

转载于:https://www.cnblogs.com/echoht/p/3680038.html

LeetCode OJ - Sort List相关推荐

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

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

  2. LeetCode OJ -- Binary Tree Paths

    http://blog.ubooksapp.com/ 标签(空格分隔): LeetCode OJ BinaryTree Given a binary tree, return all root-to- ...

  3. LeetCode 75. Sort Colors (python一次遍历,模拟三路快排)

    LeetCode 75. Sort Colors (python一次遍历,模拟三路快排) 题目分析: 本题需要实现数字只包含0,1,2的排序,并且要求一次遍历. 由于只用把数字隔离开,很容易想到快排的 ...

  4. 【排序】LeetCode 75. Sort Colors

    LeetCode 75. Sort Colors Solution1: 参考自:<leetcode-cpp 答案> 由于0,1,2非常紧凑,首先想到计数排序(counting sort), ...

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

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

  6. Leetcode 075 Sort Colors

    题目连接:Leetcode 075 Sort Colors 解题思路:从左向右遍历,同时维护两个指针r和b,0~r位置上的元素为0,b~n-1位置上的为2.在遍历过程中,碰到0,放到r的位置:碰到2, ...

  7. LeetCode OJ 147. Insertion Sort List

    Sort a linked list using insertion sort. 对链表使用插入排序还是很简单的,从链表中拆下一个节点,然后把它插入到已经排序的部分的链表中,直到所有节点都被插入.代码 ...

  8. [LeetCode]75.Sort Colors

    [题目连接] 75.Sort Colors [题目] Given an array with n objects colored red, white or blue, sort them so th ...

  9. LeetCode 75. Sort Colors--Python解法

    题目地址:Sort Colors - LeetCode Given an array with n objects colored red, white or blue, sort them in-p ...

最新文章

  1. 返回手势导致页面卡死并且UI错乱的问题解决
  2. 入门一班 20180917 软硬连接
  3. 圆你“鸟人”梦,全身VR模拟飞行器Birdly带你飞
  4. ASP.NET操作文件大全
  5. Spring发展历程总结
  6. 2阶节IIR算法C语言源码
  7. python车牌识别逆光怎么办代码_这摄像头除了能逆光识别车牌,还会跟人打招呼?...
  8. 前端基础-html-标题标签
  9. hibernate框架学习笔记11:Criteria查询详解
  10. android9 mate10,华为仅这四部手机升到安卓9.0,Mate10和P20用户窃喜!
  11. html5中不再支持的元素
  12. springboot系列二、springboot项目搭建
  13. oracle gi 创建,浅谈Oracle RAC --GI的启动
  14. hMailServer之发送附件大小限制
  15. 简书python_python爬虫(以简书为例)
  16. VirtualBox硬盘扩容
  17. 【语音识别】基于matlab傅立叶变换0-9数字语音识别【含Matlab源码 384期】
  18. laravel下载安装
  19. 基于java实现的一个电话号码程序,3位,5位,7位,8位,11位
  20. 财富杂志推荐的75本必读书

热门文章

  1. 百度 经验 apache php mysql_php+Apache环境搭建教程
  2. C程序语言表达式运算顺序,详解C++编程中表达式的语义与计算顺序
  3. mysql5.7存储json_MySQL5.7的json数据格式的问题
  4. 外卖行业现状分析_我国外卖行业发展现状与趋势一览
  5. mysql数据库之单表查询
  6. 20175333曹雅坤实验四《Android程序设计》实验报告
  7. HDU 4747 Mex【线段树上二分+扫描线】
  8. 标准JavaBean
  9. RF脚本中的坑2: pip下载python库时报certificate verify failed
  10. poj Muddy Fields