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

    xiaoxiao2021-03-26  30

    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

    转载请注明原文地址: https://ju.6miu.com/read-662661.html

    最新回复(0)