【LeetCode】148. 排序链表 结题报告 (C++)

原题地址:https://leetcode-cn.com/problems/sort-list/description/

题目描述:

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

示例 1:

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

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

 

解题方案:

本题对时间复杂度有要求:在 O(n log n) 时间复杂度和常数级空间复杂度下。因此平常使用的插入法和交换法都不能使用,这里就会想到归并法。归并之前,需要对链表进行对半拆分。

再提一下,归并两个链表的函数使用了一个小小的技巧,引入了头节点,这样在操作上比较容易返回链表。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l, ListNode* r){
        ListNode* head = new ListNode(-1);        
        ListNode* tmp = head;        
        if (!l) return r;        
        if (!r) return l;                
        while(l && r)        
        {            
            if(l->val > r->val)            
            {                
                tmp->next = r;                
                r = r->next;            
            }            
            else            
            {                
                tmp->next = l;                
                l = l->next;            
            }            
            tmp = tmp->next;        
        }        
        if(!l)          
                tmp->next = r;                  
        else         
                tmp->next = l;            
        
        return head->next;
    }

    ListNode* sortList(ListNode* head) {
        if(!head||!head->next)            
            return head;                    
        ListNode* p=head;        
        ListNode* q=head;                
        //两个指针法实现从中间切分                 
        while(q->next != NULL)          
        {              
            q = q->next->next;              
            if(q == NULL)                 
                break;                            
            p = p->next;          
        }          
        ListNode* right = p->next;        
        p->next = NULL;                
        ListNode* left = sortList(head);        
        right = sortList(right);                
        return mergeTwoLists(left, right);
    }
};

后来看了其他博主的方法,发现multimap很神奇,虽然本题要求的是常数级空间复杂度。与map不同,multimap是自动根据key值进行升序排序。map的key必须独一无二,multimap的key可以重复。multimap参考资料:https://blog.csdn.net/yutianxin123/article/details/52454252

代码如下:

/**
 * 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) {
        multimap<int,ListNode*> mul;
        while(head){
            mul.insert(make_pair(head->val,head));
            head=head->next;
        }
        ListNode* dummy(-1);
        head = dummy;
        for(auto it = mul.begin(); it != mul.end(); it ++){
            head->next = it->second;
            head = head->next;
        }
        head->next=NULL;
        return dummy->next;
    }
};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值