148. Sort List

Sort a linked list in O(n log n) time using constant space complexity.
觉得这个可以归到hard里面了
O(nlogn)的排序 首先想到的是qucik sort,merge sort之类 但是因为递归调用 会有入栈操作 空间复杂度O(logn) 

discuss里面的最高vote 就是常规的merge sort 是错误的…

第二名是正确的 code如下 

/**
 * Merge sort use bottom-up policy, 
 * so Space Complexity is O(1)
 * Time Complexity is O(NlgN)
 * stable sort
*/
class Solution {
public:
        ListNode *sortList(ListNode *head) {
                if(!head || !(head->next)) return head;
                
                //get the linked list's length
                ListNode* cur = head;
                int length = 0;
                while(cur){
                        length++;
                        cur = cur->next;
                }
                
                ListNode dummy(0);
                dummy.next = head;
                ListNode *left, *right, *tail;
                for(int step = 1; step < length; step <<= 1){
                        cur = dummy.next;
                        tail = &dummy;
                        while(cur){
                                left = cur;
                                right = split(left, step);
                                cur = split(right,step);
                                tail = merge(left, right, tail);
                        }
                }
                return dummy.next;
        }
private:
        /**
         * Divide the linked list into two lists,
     * while the first list contains first n ndoes
         * return the second list's head
         */
        ListNode* split(ListNode *head, int n){
                //if(!head) return NULL;
                for(int i = 1; head && i < n; i++) head = head->next;
                
                if(!head) return NULL;
                ListNode *second = head->next;
                head->next = NULL;
                return second;
        }
        /**
          * merge the two sorted linked list l1 and l2,
          * then append the merged sorted linked list to the node head
          * return the tail of the merged sorted linked list
         */
        ListNode* merge(ListNode* l1, ListNode* l2, ListNode* head){
                ListNode *cur = head;
                while(l1 && l2){
                        if(l1->val > l2->val){
                                cur->next = l2;
                                cur = l2;
                                l2 = l2->next;
                        }
                        else{
                                cur->next = l1;
                                cur = l1;
                                l1 = l1->next;
                        }
                }
                cur->next = (l1 ? l1 : l2);
                while(cur->next) cur = cur->next;
                return cur;
        }
};

思路:
this problem can be easily solved using recurrence and divide-and-conquer. But it consumes program stack to store the recurring function stack frame, actually it consumes o(lgn) space complexity. Recursion use up-to-bottom strategy , why not try the opposite way--bottom-to-up, luckily it works, it only consumes 0(1) space complexity and o(nlgn) time complextity.

说的挺明确的 常规的merge sort 是把集合等分成2个 4个 8个… 直到集合中只有一个元素 然后开始merge




上面这个逆向思维
比如输入是 8->1->4->3->2->7->5->6
left:1
right:8
tail:4->3->2->7->5->6
//merge left and right, and then connect with tail
merge:1->8->4->3->2->7->5->6

left:1->8
right:4->3
tail:2->7->5->6
merge:1->3->4->8->2->7->5->6



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值