zoukankan      html  css  js  c++  java
  • 【LeetCode-链表】排序链表

    题目描述

    在 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/

  • 相关阅读:
    多线程编程1-定义理解与三种实现方式
    Java类集框架详细汇总-底层分析
    Trie、并查集、堆、Hash表学习过程以及遇到的问题
    spring前导知识-Tomcat、Maven等配置
    双指针、位运算、离散化、区间合并的手动模拟
    单点登录原理与简单实现
    Spring引入外部配置文件
    Java异常机制
    Java多线程-线程的概念和创建
    java webservice服务器端获取request对象的三种方式
  • 原文地址:https://www.cnblogs.com/flix/p/13295533.html
Copyright © 2011-2022 走看看