LeetCode - Sort List

来源:互联网 发布:ubuntu修改文件所有者 编辑:程序博客网 时间:2024/06/18 17:30

https://leetcode.com/problems/sort-list/

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

这道题按题目要求就只能用quicksort了,mergesort是需要O(n)额外空间的哈。

先定义partition代码:

以tail的值为seed,比seed小的放左边,比seed大的放右边,最后seed的值和比seed大的这部分里面第一个node交换,保证middle node的值是seed,但是因为在list里面求previous是比较难的,所以返回的不是值为seed的middle node,而是middle node的前一个node, premiddle。

因此下一轮就是

quicksort(head, premiddle);

quickSort(premiddle.next.next, tail);

需要注意的情况是,当中值左边没有的时候,也就是上一次partition中没有比seed小的值时,这时的premiddle返回的是head,也是真正的middle, 所以后半部分排序应该是quickSort(premiddle.next, tail).

当中值右边没有值时,也就是上一次partition中没有比seed大的值时,这里的premiddle是tail前一个node,middle还是tail,但是这时的premiddle.next.next就是不属于当前排序范围了,所以这种情况下就不用排后半部分了。

总之因为Linkedlist排序不像array那样可以比较head,tail的下标,所以在原array中 head>tail可以一下判断出不用再排了,但是在List中head就算到了tail后面,它也可能是个valid的node, 需要考虑这种情况,再处理。

在下面代码的partition函数中,less是middle,pre是premiddle。

代码里面全是值交换,不是node交换,因为node交换需要一个非常完善的swap()函数,容易错。。。不过下次可以试下用node交换。

public class Solution {    public ListNode sortList(ListNode head) {        if(head==null || head.next==null) return head;        ListNode tail = head;        while(tail.next!=null) tail = tail.next;        quickSort(head, tail);        return head;    }        public void quickSort(ListNode head, ListNode tail){        if(head == tail || head==null || tail==null) return;        ListNode premiddle = partition(head, tail);                if(premiddle!=head) quickSort(head, premiddle);        if(premiddle == head) quickSort(premiddle.next, tail);        else if(premiddle.next!=tail && premiddle.next.next!=tail) quickSort(premiddle.next.next, tail);    }        public ListNode partition(ListNode head, ListNode tail) {        int x = tail.val;        if(head==tail || head==null || head.next==null) return head;        ListNode traverse = head;        ListNode pre = head;        ListNode less = head;        while(traverse!=tail){            if(traverse.val < x){                int tmp = less.val;                less.val = traverse.val;                traverse.val = tmp;                pre = less;                less = less.next;            }            traverse = traverse.next;        }        int tmp = less.val;        less.val = tail.val;        tail.val = tmp;        return pre;    }}


0 0