LeetCode 148. 排序链表

难度:中等。
标签:链表,双指针,分治,排序,归并排序。

归并排序,注意处理一段链表,要注意这一段链表的前后节点的连接。

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

    pair<ListNode*, ListNode*> merge(ListNode* A, int lenA, ListNode* B, int lenB){
        ListNode* head = nullptr;
        ListNode* cur = nullptr;
        int a = 0, b = 0;
        while(a < lenA && b < lenB){
            if(A->val < B->val){
                if(head == nullptr){
                    head = new ListNode(A->val);
                    cur = head;
                }
                else{
                    cur->next = new ListNode(A->val);
                    cur = cur->next;
                }
                a++;
                A = A->next;
            }
            else{
              if(head == nullptr){
                    head = new ListNode(B->val);
                    cur = head;
                }
                else{
                    cur->next = new ListNode(B->val);
                    cur = cur->next;
                }
                b++;
                B = B->next;
            }
        }

        while(a < lenA){
            cur->next = A;
            A = A->next;
            cur = cur->next;
            a++;
        }

        while(b < lenB){
            cur->next = B;
            B = B->next;
            cur = cur->next;
            b++;
        }
        return {head, cur};
    }
    

    ListNode* mergeSort(ListNode* nodeA, int n, ListNode* pre, ListNode* next){
        if(n > 1){
            ListNode* nodeB = nodeA;
            ListNode* tailA = nodeA;
            int part1 = n / 2, part2 = n - part1;
            for(int i = 0; i < part1; ++i){
                tailA = nodeB;
                nodeB = nodeB->next;
            }
            ListNode* headA = mergeSort(nodeA, part1, pre, nodeB);
            ListNode* headB = mergeSort(nodeB, part2, tailA, next);

            auto pair3 = merge(headA, part1, headB, part2);
            ListNode* head = pair3.first, *tail = pair3.second;
            if(pre != nullptr)pre->next = head;
            tail->next = next;
            return head;
        }
        return nodeA;
    }
    
public:
    ListNode* sortList(ListNode* head) {
        int len = 0;
        ListNode* temp = head;
        while(temp != nullptr){
            len++;
            temp = temp->next;
        }
        return mergeSort(head, len, nullptr, nullptr);
    }
};

结果:
在这里插入图片描述
怎么这么慢呢。

看下题解,优化一下。
题解并没有使用长度来标定一段链表,而是将一段链表指向的下一个节点置为nullptr,然后对两个链表进行归并排序。

正确解法:

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

    ListNode* merge(ListNode* A, ListNode* B){
        ListNode* head = nullptr;
        ListNode* cur = nullptr;
        while(A != nullptr && B != nullptr){
            if(A->val < B->val){
                if(head == nullptr){
                    head = A;
                    cur = head;
                }
                else{
                    cur->next = A;
                    cur = cur->next;
                }
                A = A->next;
            }
            else{
              if(head == nullptr){
                    head = B;
                    cur = head;
                }
                else{
                    cur->next = B;
                    cur = cur->next;
                }
                B = B->next;
            }
        }

        if(A != nullptr){
            cur->next = A;
        }
        if(B != nullptr){
            cur->next = B;
        }
        return head;
    }
    

    ListNode* mergeSort(ListNode* head, ListNode* tail){
        if(head == nullptr){
            return head;
        }
        if(head->next == tail){
            head->next = nullptr;
            return head;
        }
        ListNode* mid = head, *fast = head;
        while(fast != tail && fast->next != tail){
            mid = mid->next;
            fast = fast->next->next;
        }

        ListNode* head1 = mergeSort(head, mid);
        ListNode* head2 = mergeSort(mid, tail);
        ListNode* newHead = merge(head1, head2);

        return newHead;
    }
    
public:
    ListNode* sortList(ListNode* head) {
        return mergeSort(head, nullptr);
    }
};

结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值