LeetCode - Sort List
2014-04-15 17:02
197 查看
作者:disappearedgod
文章出处:/article/3730067.html
时间:2014-4-16
Sort a linked list in O(n log n) time using constant space complexity.
Java
这里规定了时间复杂度,所以有些排序像插入排序、选择排序等这类时间复杂度上界为θ(n^2)的算法就不适合。
链表的排序是用一个跳一步的walker和一个跳两步的runner来写的,我首先参照了Coder_Ganker的博客 http://blog.csdn.net/linhuanmars/article/details/21133949
但是,由于单链表不能像数组那样随机存储,和数组的快排序相比较,还是有一些需要注意的细节:
支点的选取,由于不能随机访问第K个元素,因此每次选择支点时可以取待排序那部分链表的头指针
遍历量表方式,由于不能从单链表的末尾向前遍历,因此使用两个指针分别向前向后遍历的策略实效
事实上,可以可以采用一趟遍历的方式将较小的元素放到单链表的左边。具体方法为:
定义两个"指针"walker, runner,其中walker指单链表头结点,runner指向单链表头结点的下一个结点
runner = runner.next.next
使用runner遍历单链表,每遇到一个比支点小的元素,就和walker进行数据交换,然后令walker=walker.next
java代码为
Solution(持续更新,java>c++)
文章出处:/article/3730067.html
时间:2014-4-16
题目
Sort List
Sort a linked list in O(n log n) time using constant space complexity.Java
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */public class Solution { public ListNode sortList(ListNode head) { } }
解题
破题
这里规定了时间复杂度,所以有些排序像插入排序、选择排序等这类时间复杂度上界为θ(n^2)的算法就不适合。
一般解法
链表的排序是用一个跳一步的walker和一个跳两步的runner来写的,我首先参照了Coder_Ganker的博客 http://blog.csdn.net/linhuanmars/article/details/21133949 思想(理论知识):
单链表的快速排序和数组的快速排序在基本细想上是一致的,以从小到大来排序单链表为例,都是选择一个支点,然后把小于支点的元素放到左边,把大于支点的元素放到右边。但是,由于单链表不能像数组那样随机存储,和数组的快排序相比较,还是有一些需要注意的细节:
支点的选取,由于不能随机访问第K个元素,因此每次选择支点时可以取待排序那部分链表的头指针
遍历量表方式,由于不能从单链表的末尾向前遍历,因此使用两个指针分别向前向后遍历的策略实效
事实上,可以可以采用一趟遍历的方式将较小的元素放到单链表的左边。具体方法为:
定义两个"指针"walker, runner,其中walker指单链表头结点,runner指向单链表头结点的下一个结点
runner = runner.next.next
使用runner遍历单链表,每遇到一个比支点小的元素,就和walker进行数据交换,然后令walker=walker.next
java代码为
public class Solution { public ListNode sortList(ListNode head) { return mergeSort(head); } private ListNode mergeSort(ListNode head){ if(head==null || head.next == null) return head; ListNode walker = head; ListNode runner = head; while(runner.next!=null && runner.next.next!=null){ walker = walker.next; runner = runner.next.next; } ListNode head2 = walker.next; walker.next = null; ListNode head1 = head; head1 = mergeSort(head1); head2 = mergeSort(head2); return merge(head1,head2); } private ListNode merge(ListNode head1, ListNode head2){ ListNode helper = new ListNode(0);//把栈空间算上的话还是需要O(logn)的空间的 helper.next = head1; ListNode pre = helper; while(head1!=null && head2 != null ){ if(head1.val < head2.val){ head1= head1.next; } else{ ListNode next = head2.next; head2.next = pre.next; pre.next = head2; head2 = next; } pre = pre.next; } if(head2!=null){ pre.next = head2; } return helper.next; } }
后记
抛开时间限制,练习一下写单链表排序,首先写一下插入排序private ListNode insertSort(ListNode head){ ListNode pre_base = head; ListNode base = head; ListNode pre_cmp = head; ListNode cmp = head; ListNode next; if(head ==null || head.next ==null) return head; for( int i =0;base.next!=null; pre_base = base,base=head.next,i++){ for(int j =i; j>0 && less(base,cmp);pre_cmp=cmp,cmp = cmp.next,j--) { //exch(pre_base,base,pre_cmp,cmp); next = base.next; base.next = cmp.next; cmp.next = next; pre_base.next = cmp; pre_cmp.next = base; } } return head; } private void exch(ListNode pre_i,ListNode i,ListNode pre_j, ListNode j){ ListNode next = i.next; i.next = j.next; j.next = next; pre_i.next = j; pre_j.next = i; } private boolean less(ListNode i,ListNode j){ return i.val<j.val; }
返回
LeetCodeSolution(持续更新,java>c++)
相关文章推荐
- 编程精华资源大汇总
- 制作一个链表的方法
- MyBatis多参数传递之注解方式示例
- GPS NMEA码格式
- 软考历程(1)——操作系统
- css中定位中的absolute和relative是什么意思
- 6.8 final 关键字 和 6 . 8 . 1 f i n a l 数据
- 数据生成器。。。
- Config程序配置文件操作实践及代码详注
- 算法笔记整理
- Servlet创建、编译、部署、运行
- SHELL脚本分支结构之if
- tesseract-ocr 图像识别所遇到的些问题
- XHTML标签的嵌套规则
- placeholder在不同浏览器下的表现及兼容方法
- javascript中的2个感叹号的用法
- user profile信息同步问题
- Servlet创建、编译、部署、运行
- 网络传输数据封装详解(IP,UDP,TCP)
- (WPF) 文件和文件夹选择对话框。