148. 排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4
示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

用归并排序解决,归并排序有两种写法,所以有两种方法。
方法一:(迭代的归并排序)

//用快慢指针即可找到链表的中点,然后用归并算法cut and merge(递归和迭代都可以)
/**
 * 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 *fast=head, *slow=head;
        while(!fast||!fast->next){ //用快慢指针,此时slow指向中点
            fast=fast->next->next;
            slow=slow->next;
        }
        ListNode *temp = slow->next;
        slow->next=NULL;
        return merge(sortList(head),sortList(temp)); //sortList()即对左/右边进行递归处理,最后用merge函数合并
    }

    //再写一个merge函数,参考leetcode21题即可
    ListNode* merge(ListNode *l1,ListNode *l2){
        ListNode *dummyhead = new ListNode(0);
        ListNode *p=dummyhead;
        while(l1!=NULL && l2 !=NULL){
            if(l1->val<l2->val){
                p->next=l1;
                l1=l1->next;
                p=p->next;
            }
            else{
                p->next=l2;
                l2=l2->next;
                p=p->next;
            }
        }
        p->next=NULL;
        if(l1!=NULL) p->next=l1;
        if(l2!=NULL) p->next=l2;
        return dummyhead->next;
    }
};

方法二:递归的归并排序,但是有一个案例超时,因为本题要求常数级空间复杂度。

//用快慢指针即可找到链表的中点,然后用归并算法cut and merge(递归和迭代都可以)
/**
 * 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 *fast=head, *slow=head;
        while(!fast||!fast->next){ //用快慢指针,此时slow指向中点
            fast=fast->next->next;
            slow=slow->next;
        }
        ListNode *temp = slow->next;
        slow->next=NULL;
        return merge(sortList(head),sortList(temp)); //sortList()即对左/右边进行递归处理,最后用merge函数合并
    }

    //再写一个merge函数,参考leetcode21题即可
    ListNode* merge(ListNode* l1, ListNode* l2) {
        if (!l1) return l2;
        if (!l2) return l1;
        if (l1->val < l2->val) {
            l1->next = merge(l1->next, l2);
            return l1;
        } else {
            l2->next = merge(l1, l2->next);
            return l2;
        }
    }
};

你可能感兴趣的:(LeetCode)