zoukankan      html  css  js  c++  java
  • 【栈】栈排序

    LeetCode 面试题 03.05. 栈排序

    题目描述

    栈排序。 编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:push、pop、peek 和 isEmpty。当栈为空时,peek 返回 -1。

    示例1:

    输入:
    ["SortedStack", "push", "push", "peek", "pop", "peek"]
    [[], [1], [2], [], [], []]
    输出:
    [null,null,null,1,null,2]

    示例2:

    输入:
    ["SortedStack", "pop", "pop", "push", "pop", "isEmpty"]
    [[], [], [], [1], [], []]
    输出:
    [null,null,null,null,null,true]

    说明:

    1. 栈中的元素数目在[0, 5000]范围内。

    解题思路

    1. 单栈排序
      灵感来源于 O(1)空间复杂度反转栈 这道题。
      题目没说让我们一次返回排好序的栈,只是要我们提供 push/pop/peek 这些栈的普通接口,所以我们可以把排序的工作降为获取栈内最小元素。
      这样思路就很简单了,递归拿出元素进行比较就可以 —— 不用临时数组存元素,就用函数调用栈空间存元素嘛!
      时间复杂度上,push 是 O(1) 但是 pop 和 peak 都是 O(n)。

    2. 双栈排序
      题目说可以用一个临时栈,那我们就可以把上面的递归改成循环,把函数调用栈上的数据存入普通栈。
      实际上,这才是大多数人的做法。
      这种做法,维护了一个有序的栈,排序发生在 push 阶段,peak 和 pop 都是 O(1) 操作,只有 push 是 O(n)。

    参考代码

    1. 单栈排序

    // 最小元素在栈顶的栈
    class SortedStack {
        stack<int> stk;
        int pickMin() {
            int val = stk.top();
            stk.pop();
            if (stk.empty()) return val;
            int val2 = pickMin();
            if (val <= val2) {
                stk.push(val2);
                return val;
            } else {
                stk.push(val);
                return val2;
            }
        }
    public:
        SortedStack() {
    
        }
        
        void push(int val) {
            stk.push(val);
        }
        
        void pop() { // 空的时候也可能调用pop
            if (!isEmpty()) pickMin();
        }
        
        int peek() {
            if (isEmpty()) return -1;
            int val =  pickMin();
            stk.push(val);
            return val;
        }
        
        bool isEmpty() {
            return stk.empty();
        }
    };
    
    /**
     * Your SortedStack object will be instantiated and called as such:
     * SortedStack* obj = new SortedStack();
     * obj->push(val);
     * obj->pop();
     * int param_3 = obj->peek();
     * bool param_4 = obj->isEmpty();
     */
    

    2. 双栈排序

    这里insert操作的时候要特别注意 stk 为空的情况。下面的两种写法,第二种写法更好,把判空始终放在while条件,从而把第一次插入元素和插入最大元素的两种情况统一了起来。

    // 最小元素在栈顶的栈
    class SortedStack {
        stack<int> stk;
        stack<int> tmp;
    /*
        void InsertSortedStack(int val) {
            if (stk.empty()) {
                stk.push(val);
                return;
            }
            int top = stk.top();
            while (val > top) {
                tmp.push(top);
                stk.pop();
                if (stk.empty()) break;
                top = stk.top();
            }
            stk.push(val);
            while (!tmp.empty()) {
                top = tmp.top();
                tmp.pop();
                stk.push(top);
            }
        } // AC
    */
        void InsertSortedStack(int val) {
            while (!stk.empty()) {
                int top = stk.top();
                if (val <= top) break;
                tmp.push(top);
                stk.pop();
            }
            stk.push(val);
            while (!tmp.empty()) {
                int top = tmp.top();
                tmp.pop();
                stk.push(top);
            }
        } // AC
    public:
        SortedStack() {
    
        }
        
        void push(int val) {
            InsertSortedStack(val);
        }
        
        void pop() {
            if (!isEmpty()) stk.pop();
        }
        
        int peek() {
            if (isEmpty()) return -1;
            return stk.top();
        }
        
        bool isEmpty() {
            return stk.empty();
        }
    }; // AC
    
  • 相关阅读:
    mysql 创建数据库 添加用户 数据库授权给某用户
    Storm近年的发展
    Doris 最佳实践-Compaction调优
    pickle,struct,ujson,orjson 模块
    python用prettytable输出漂亮的表格
    nginx自定义访问日志
    事务 知识点梳理
    14
    13
    8
  • 原文地址:https://www.cnblogs.com/zhcpku/p/15333692.html
Copyright © 2011-2022 走看看