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/

  • 相关阅读:
    C#中的编译为什么不叫Compile而叫build
    类型(Type)
    C#中关于值类型和引用类型的区别
    php通用化api格式输出
    tp6获取参数的五种办法
    PHP 数组------分割、合并
    explain结果中的type字段的含义
    order by 排序
    SQL开发技巧
    tp5模板输出日期时间
  • 原文地址:https://www.cnblogs.com/flix/p/13295533.html
Copyright © 2011-2022 走看看