[Leetcode Solution] Sort List

Sort a singly-linked list is easy with quick sort and merge sort algorithm. 

The worst case run time of quick sort is O(n ^ 2). Whereas merge sort is a stable sort with O(n logn) complexity, and it is a in-place algorithm to sort the linked list.


This code implements a quick sort alogirthm with python. Got an AC with a simple trick. Because the test data only contains "bad cases" but not the "worst cases". 

If there is a test case "[100000, 99999, 99998 ... ... 0]" , my code will take a long time to get the result. Duh...


class Solution:
    # @param head, a ListNode
    # @return a ListNode
    def sortList(self, head):
        if not head:
            return head
            
        pivot = head
        xs = head.next
        
        left, right = self.partition(xs, pivot)
        
        left = self.sortList(left)
        right = self.sortList(right)
        

        pivot.next = right
        if left:
            ptr = left
            while ptr.next:
                ptr = ptr.next
            ptr.next = pivot
            return left
        else:
            return pivot
            
    def partition(self, head, pivot):
        left = right = None
        leftPtr = rightPtr = None
        
        while head:
            if head.val <= pivot.val:
                if not left:
                    left = leftPtr = head
                else:
                    leftPtr.next = head
                    leftPtr = leftPtr.next
                
            else:
                if not right:
                    right = rightPtr = head
                else:
                    rightPtr.next = head
                    rightPtr = rightPtr.next
            
            head = head.next
            
        if leftPtr:
            leftPtr.next = None
        if rightPtr:
            rightPtr.next = None
        
        return left, right


Here is the merge-sort version. Merge sort is an easy approach to the result, just divides the linked-list into two, and conquer one by one.

But there is a knack in divide a link-list into two same length sub-lists. You can see it in the code.


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

class Solution {
public:
    ListNode *sortList(ListNode *head)
    {
        if (!head || !head->next) return head;
        
        ListNode *left, *right;
        partition(head, left, right);
        left = sortList(left);
        right = sortList(right);
        
        head = NULL;
        ListNode *ptr = NULL;
        while (left && right) {
            ListNode *now = NULL;
            if (left -> val <= right -> val) {
                now = left;
                left = left -> next;
            } else {
                now = right;
                right = right -> next;
            }
            
            if (!head) {
                head = now;
                ptr = head;
                ptr -> next = NULL;
            } else {
                ptr -> next = now;
                ptr = ptr -> next;
            }
        }
        if (left) {
            ptr -> next = left;
        }
        if (right) {
            ptr -> next = right;
        }
        return head;
    }
    
    void partition(ListNode *head, ListNode* &left, ListNode* &right)
    {
        if (!head) {
            left = right = NULL;
            return;
        } else if (!head -> next) {
            left = head;
            right = NULL;
            return;
        }
        ListNode *a, *b;
        a = b = head;
        
        while (true) {
            b = b -> next;
            if (!b) break;
            b = b -> next;
            if (!b) break;
            a = a -> next;
        }
        right = a -> next;
        a -> next = NULL;
        left = head;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值