leetCode刷题归纳-List(148 Sort List)

来源:互联网 发布:linux清除文件夹内容 编辑:程序博客网 时间:2024/05/22 04:55

148. Sort List

中等难度,但是需要用到divide & conquer的思想,个人感觉还是比较有难度,题目描述如下:

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

要求时间复杂度为O(n log n)空间复杂度为O(1),分析可知,只能用分治的思想来完成才能达到要求,因为只有分治,每次处理一个partition才会是常数空间。
排序的方法是mergesort,mergesort的步骤一般分为分段(partition)与合并(merge),代码如下:

public class Solution {    public ListNode sortList(ListNode head) {        if (head == null || head.next == null)            return head;        ListNode f = head.next.next;        ListNode p = head;        //这样的移动方法可以将p移动到list中心,是list移动到中心的常用方法        while (f != null && f.next != null) {            p = p.next;            f =  f.next.next;        }        //h2代表每个已排序部分的头指针        ListNode h2 = sortList(p.next);        //这里每次选择p->next迭代是非常有必要的,因为链表不能访问前一个元素,每次迭代完成后p都恰好代表已排序链表的**前一个元素**,通过p->next=NULL可以达到断链的作用        p.next = null;        return merge(sortList(head), h2);    }    //归并部分,通过对两部分已经排序过的数列进行比较进行归并    public ListNode merge(ListNode h1, ListNode h2) {        ListNode newHead = new ListNode(Integer.MIN_VALUE);        ListNode c = hn;        while (h1 != null && h2 != null) {            if (h1.val < h2.val) {                c.next = h1;                h1 = h1.next;            }            else {                c.next = h2;                h2 = h2.next;            }            c = c.next;        }        //剩下的数字都是比较大的数字,直接连接起来就好了        pt->next=h1?h1:h2;        return newHead.next;    }}

以5-1-4-3-2->NULL的链表为例,排序的过程是(从后往前):

 1. 5 1 4 2 3 (merge (2)(3)) 2. 5 1 2 3 4 (merge (4)(2 3))//h2=sortList(head); 3. 1 5 2 3 4(merge(1) (5))//return merge(sortList(head), h2)中的sortList(head) 4. 1 2 3 4 5(merge(1 5)(2 3 4))//return merge(sortList(head), h2) 
0 0
原创粉丝点击