sort-list

博客围绕在O(n log n)时间复杂度和常数空间复杂度下对链表排序展开。采用自底向上的归并排序方法,先将左右待合并链表切开,把结尾节点的next设为NULL,每次合并完后,让上一个合并链表尾部的next指向当前合并链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 题目:sort a linked list in O(n log n) time using constant space complexity.
  • idea:
  1. 使用自底向上来归并排序链表,首先将左右两个待合并的链表分别cut切开,即将左右两个链表的结尾节点的next设置为NULL
  2. 每次合并完两个链表以后将上一个合并完的链表的尾部的next指向当前合并完的链表
  • 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) {
        int len = 0;
        auto p = head;
        while(p){
            len++;
            p = p->next;
        }
        for (unsigned size = 1; size < len; size *= 2){
            
            auto left = head;
            
            auto right = cut(left, size);
            auto cur = cut(right, size);
            head = merge(left, right);
            auto tail = head;
            while (tail->next){
                tail = tail->next;
            }
            int count = 0;
            while(cur){
                auto left = cur;
                auto right = cut(left, size);
                cur = cut(right, size);
                tail->next = merge(left, right);
                while (tail->next){
                    tail = tail->next;
                }
            }
            
        }
        return head;
    }
    
    ListNode* cut(ListNode *p, int size){
        while (p && --size){
            p = p->next;
        }
        if (!p) return NULL;
        auto res = p->next;
        p->next = NULL;
        return res;
    }
    
    ListNode* merge(ListNode *p1, ListNode *p2){
        if (!p2) return p1;
        ListNode *head;
        if (p1->val < p2->val) head = p1, p1 = p1->next;
        else head = p2, p2 = p2->next;
        
        auto p = head;
        while (p1 && p2){
            if (p1->val < p2->val){
                p->next = p1; 
                p1 = p1->next;
            }
            else{
                p->next = p2;
                p2 = p2->next;
            }    
            p = p->next;
        }
        p->next = p1?p1:p2;
        return head;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值