码迷,mamicode.com
首页 > 编程语言 > 详细

【LeetCode-链表】排序链表

时间:2020-07-13 21:56:15      阅读:71      评论:0      收藏:0      [点我收藏+]

标签:image   html   src   efi   时间   ble   tac   top   lse   

题目描述

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

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

题目链接: https://leetcode-cn.com/problems/sort-list/

思路1

使用两个栈来做,类似于栈排序的方法。代码如下:

/**
 * 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) {
        if(head==nullptr) return head;

        stack<ListNode*> s;
        stack<ListNode*> help; // 辅助栈
        ListNode* cur = head;
        while(cur!=nullptr){
            if(s.empty()) s.push(cur);
            else{
                while(!s.empty() && cur->val>s.top()->val){
                    help.push(s.top()); s.pop();
                }
                s.push(cur);
                while(!help.empty()){
                    s.push(help.top()); help.pop();
                }
            }
            cur = cur->next;
        }

        ListNode* dummy = new ListNode(0);
        cur = dummy;
        while(!s.empty()){
            ListNode* node = s.top(); s.pop();
            node->next = nullptr;
            cur->next = node;
            cur = cur->next;
        }
        return dummy->next;
    }
};
// 超时

这种方不满足 O(n log n) 时间复杂度和常数级空间复杂度,并且会超时。

思路2

使用归并排序。

先划分,当前节点为空或者当前节点的下一个节点为空就返回合并。在分割的时候需要找到链表的中点分割。如果链表长度是奇数,则只有唯一的重点;如果链表长度是偶数,则有两个中点,需要使用左边的中点,具体可参考链表的中间节点
技术图片

代码如下:

/**
 * 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) {
        if(head==nullptr || head->next==nullptr) return head;

        ListNode* slow = head;
        ListNode* fast = head;
        while(fast->next!=nullptr && fast->next->next!=nullptr){
            fast = fast->next->next;
            slow = slow->next;
        } 

        ListNode* temp = slow->next;
        slow->next = nullptr;
        ListNode* left = sortList(head);
        ListNode* right = sortList(temp);

        ListNode* dummy = new ListNode(0);
        ListNode* cur = dummy;
        while(left!=nullptr && right!=nullptr){
            if(left->val<right->val){
                cur->next = left;
                left = left->next;
            }else{
                cur->next = right;
                right = right->next;
            }
            cur = cur->next;
        }
        cur->next = (left==nullptr? right:left);
        return dummy->next;
    }
};
  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(logn)

参考

https://leetcode-cn.com/problems/sort-list/submissions/

【LeetCode-链表】排序链表

标签:image   html   src   efi   时间   ble   tac   top   lse   

原文地址:https://www.cnblogs.com/flix/p/13295533.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!