[每日一题][找工作第27天][2025-10-19] Leetcode 148. 排序链表(虽然勉强通过,实际上应该算是失败了😂)

题目

148. 排序链表
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。


  •  
    示例 1:

    输入:head = [4,2,1,3]
    输出:[1,2,3,4]
    示例 2:

    输入:head = [-1,5,3,4,0]
    输出:[-1,0,3,4,5]
    示例 3:
    输入:head = []
    输出:[]
     
    提示:
  • 链表中节点的数目在范围 [0, 5 * 104] 内
  • -105 <= Node.val <= 105
     
    进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

我的代码(Python)

/**
 * 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 {
private:
    void sortListInner(ListNode* prev, ListNode* endNode = nullptr) {
        if (!prev || prev == endNode || !prev->next || prev->next == endNode || !prev->next->next || prev->next->next == endNode) return;
        int cnt = 0;
        for(ListNode* t = prev->next; t && t != endNode; t = t->next) {
            cnt++;
        }
        ListNode* t0 = prev;
        ListNode* t1 = prev->next;
        for (int i = 0; i < cnt / 2; i++) {
            t0 = t1;
            t1 = t1->next;
        }
        ListNode* middle = t1;
        t0->next = t1->next;
        t1->next = prev->next;
        prev->next = t1;

        // ListNode* middle = prev->next;
        ListNode* tmp0 = middle;
        ListNode* tmp1 = middle->next;
        ListNode* tmp2 = nullptr;
        while (tmp1 && tmp1 != endNode) {
            tmp2 = tmp1->next;
            if (tmp1->val <= middle->val) {
                ListNode* tmp = prev->next;
                prev->next = tmp1;
                tmp1->next = tmp;
                tmp0->next = tmp2;
                tmp1 = tmp2;
            } else {
                tmp0 = tmp1;
                tmp1 = tmp2;
            }
        }
        sortListInner(prev, middle);
        sortListInner(middle, endNode);
    }
public:
    ListNode* sortList(ListNode* head) {
        ListNode* prev = new ListNode(0, head);
        sortListInner(prev);
        ListNode* result = prev->next;
        delete prev;
        return result;        
    }
};

点评

要求O(nlogn),脑海中第一个想法就是快排,所以用链表来实现快速排序。
不过忽略了递归调用的空间消耗,不是O(1),而是O(logn).
另外我一开始直接取head作为分界点进行前后大小的比较基准,但是这样做在链表本身是倒序排列时,会退化成O(n^2)复杂度,所以在某个case上超时。
因此我还做了一次遍历来找中间结点😂正常来说,快排应该取随机结点才对。
最后勉强通过了测试,但是实在不是个好结果。
官方自底向上的归并排序其实应该算是比较基础的想法了,但是不熟悉,想不到这个方向……


baddif@gmail.com

AI简历优化站

Nonpareil.me:优化简历,助力职场
开源代码

AI求职跟踪器(建设中)

开源代码

主站(建设中)

Nonpareil Me

相关平台

Github Issues / Notion / Blog

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部