【Leetcode】148. Sort List

Question:

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

Tips:给一个单链表按照val进行排序。

思路:题目要求时间复杂度为nlog(n) 这是归并排序的时间复杂度,即采用分治的方法进行排序。(归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。)

①将链表分为两部分。如果是数组可以直接定位,但是对于链表需要,通过指针才能找到链表中间位置。两个速度不同的指针,可以找到链表的中间位置。

slow=slow.next;
fast=fast.next.next;

②分别将前后两部分排序,这是需采用递归来完成。

③将左右两部分合并。

代码:

 public ListNode sortList(ListNode head) {
         if(head==null ||head.next==null)
             return head;
         ListNode pre=null;
         ListNode slow=head;
         ListNode fast=head;
         //slow将为右半部分的头结点
         while(fast!=null && fast.next!=null){
             pre=slow;
             slow=slow.next;
             fast=fast.next.next;
         }
         pre.next=null;
         //递归的排序左右两部分
         ListNode l1=sortList(head);
         ListNode l2=sortList(slow);
         ListNode list=merge(l1,l2);
        return list;
            
        }
//合并两个链表
    private ListNode merge(ListNode l1, ListNode l2) {
        if(l1==null) return l2;
        if(l2==null) return l1;
        ListNode l=new ListNode(-1);
        ListNode node=l;
        while(l1!=null && l2!=null){
            if(l1.val>=l2.val){
                l.next=l2;
                l2=l2.next;
            }else{
                l.next=l1;
                l1=l1.next;
            }
            l=l.next;
        }
        //l1 l2中有不为空的直接接在后面
        if(l1!=null){
            l.next=l1;
        }
        if(l2!=null){
            l.next=l2;
        }
        return node.next;
    }

 

posted @ 2018-02-24 12:05  于淼  阅读(108)  评论(0编辑  收藏  举报