[leetcode-排序]--148. Sort List

来源:互联网 发布:mac svn服务器地址 编辑:程序博客网 时间:2024/05/01 11:15

Question: 148. Sort List

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

中文:使用恒定的空间复杂度排序一个链表,要求时间复杂度是O(nlogn)

我们知道题目的要求是时间复杂度是O(nlogn), 很自然我们就想到了二路归并排序或则是快速排序。碎玉快速排序来说,设计到大量的精准索引定位,所以对于双链表来说更加适合,而这里是单链表,所以我选择二路归并排序。

下面有一篇博文是关于二路归并排序的,不过是用数组实现的。
http://blog.csdn.net/u010853261/article/details/54894057

现在我们这里需要用单链表实现,唯一的区别就是链表的分片,这里的分片我们选用的方法是双指针法,每次一个指针后移一位,另外一个后移两位。

/** * 合并两个有序链表 * @param l1 * @param l2 * @return */private static ListNode merge(ListNode l1, ListNode l2) {    ListNode l = new ListNode(0), p = l;    while (l1 != null && l2 != null) {        if (l1.val < l2.val) {            p.next = l1;            l1 = l1.next;        } else {            p.next = l2;            l2 = l2.next;        }        p = p.next;    }    if (l1 != null)        p.next = l1;    if (l2 != null)        p.next = l2;    return l.next;}/** * 链表的二路归并排序 * @param head * @return */public static ListNode sortList(ListNode head) {    //空链表或则只有一个结点,直接返回head    if(head == null || head.next==null){        return head;    }    //1. 将list 切分为两个部分    ListNode prev=null, slow=head, fast=head;    while (fast !=null && fast.next !=null){        prev = slow;        slow = slow.next;//slow指针后移一个数据        fast = fast.next.next;//fast指针后移两个数据    }    prev.next = null;//将链表切断    //分别排序前后两个部分    ListNode l1 = sortList(head);    ListNode l2 = sortList(slow);    return merge(l1, l2);}

测试用例:

public static void main(String[] args) {    ListNode head = new ListNode(0);    ListNode n1 = new ListNode(2);    ListNode n2 = new ListNode(4);    ListNode n3 = new ListNode(1);    ListNode n4 = new ListNode(3);    head.next = n1;    n1.next = n2;    n2.next=n3;    n3.next =n4;    ListNode h =  sortList(head);    while (h!=null){        System.out.print(h.val + ",");        h = h.next;    }}

运行结果:

0,1,2,3,4,

本文完整代码的github地址:
https://github.com/leetcode-hust/leetcode/blob/master/louyuting/src/leetcode/Question148.java

0 0
原创粉丝点击