Leetcode 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

class Solution {

public:

    ListNode* sortList(ListNode* head) {
        ListNode newHead(0);//头结点
        newHead.next = head;
        ListNode* p = head;
        int length = 0;
        while (p) {//统计长度
            length++;
            p = p->next;
        }
        for (int size = 1; size < length; size*=2) {//size*=2
            ListNode* cur = newHead.next;
            ListNode* tail = &newHead;
            while (cur) {
                ListNode* left = cur;//要合并的左部链表的第一个结点
                ListNode* right = cut(left, size); // 要合并的右部分链表的第一个结点 left->@->@ right->@->@->@...
                cur = cut(right, size); //下次要合并的左部分链表 left->@->@ right->@->@  cur->@->...//下一次while的开头

                tail->next = merge(left, right);//执行合并 然后挂在tail后
                while (tail->next) {
                    tail = tail->next;//重新找到tail
                }
            }
        }
        return newHead.next;
    }
    //对链表head 从第n个截断 然后返回截断后第二个的头
    ListNode* cut(ListNode* head, int n) {
        ListNode* p = head;
        while (--n && p) {
            p = p->next;
        }
        if (!p) return nullptr;
        ListNode* next = p->next;
        p->next = nullptr;
        return next;
    }
    //两个有序链表归并
    ListNode* merge(ListNode* l1, ListNode* l2) {
        ListNode newHead(0);
        ListNode* p = &newHead;
        while (l1 && l2) {
            if (l1->val < l2->val) {
                p->next = l1;
                p = l1;
                l1 = l1->next;
            }
            else {
                p->next = l2;
                p = l2;
                l2 = l2->next;
            }
        }
        p->next = l1 ? l1 : l2;
        return newHead.next;
    }
};

 

posted @ 2020-07-02 13:08  lancelee98  阅读(110)  评论(0编辑  收藏  举报