博客
关于我
如何在O(1)时间复杂度获取栈中最大值和最小值
阅读量:409 次
发布时间:2019-03-05

本文共 2703 字,大约阅读时间需要 9 分钟。

问题描述:

  如何在O(1)时间复杂度获取栈中的最大值和最小值?

问题分析:

  普通栈规定的push(入栈)、pop(出栈)、peek(查看栈顶)等操作都只能在栈顶上操作,如果栈中元素是有序的,那么我们就可以记录栈顶和栈底元素完成问题要求,但这是不可能的。普通栈不能解决问题,显然我们需要重新定义一种新的栈结构。能否在栈中定义两个变量min和max记录最小值和最大值呢,答案是否定的,因为并不是只有进栈操作,经过一系列出栈操作后,有可能最开始的最大值和最小值已经出栈。为了解决这个问题,我们就需要两个辅助栈记录栈的每个状态下的最大值和最小值。

算法描述:

  定义一个minStack栈和一个maxStack栈,分别在栈顶保存当前栈内最小值和最大值,以minStack为例,每次有元素入栈,就与minStack的栈顶元素比较,若小于栈顶元素,则入栈成为新的栈顶元素,若大于栈顶元素,则入栈原先的栈顶元素,maxStack栈与上述思路相同。出栈时,三个栈都需要出栈。定义getMin与getMax函数分别返回minStack和maxStack栈顶元素,实现在O(1)时间复杂度获取栈中的最小值和最大值。

性能分析:

  时间复杂度:O(1)  

  空间复杂度:O(N)

  加入两个辅助栈实现O(1)时间复杂度获取栈中的最大值和最小值,典型的以空间换取时间。

代码实现:

// Java代码class MyStack {    public void push(int e) {// 新建MyStack数据结构的push函数        stack.push(e);// 元素入栈        // 判断是否需要更新minStack栈顶元素        if (minStack.isEmpty() || e < minStack.peek()) {            minStack.push(e);// 入栈元素更小,更换栈顶元素        } else if (e >= minStack.peek()) {            minStack.push(minStack.peek());// 不用更换栈顶元素        }        // 判断是否需要更新maxStack栈顶元素        if (maxStack.isEmpty() || e > maxStack.peek()) {            maxStack.push(e);// 入栈元素更大,更换栈顶元素        } else if (e <= maxStack.peek()) {            maxStack.push(maxStack.peek());// 不用更换栈顶元素        }    }    public int pop() {// 新建MyStack数据结构的pop函数        // 三栈全部出栈        int ret = stack.pop();        minStack.pop();        maxStack.pop();        return ret;    }    public int getMin() {// O(1)时间返回最小值        return minStack.peek();    }    public int getMax() {// O(1)时间返回最大值        return maxStack.peek();    }        private Stack
stack = new Stack<>();// 存储栈 private Stack
minStack = new Stack<>();// 最小值辅助栈 private Stack
maxStack = new Stack<>();// 最大值辅助栈}
// C++代码class MyStack {public:    void push(int e) {// 新建MyStack数据结构的push函数        stacks.push(e);// 元素入栈        // 判断是否需要更新minStack栈顶元素        if (minStack.empty() || e < minStack.top()) {            minStack.push(e);// 入栈元素更小,更换栈顶元素        } else if (e >= minStack.top()) {            minStack.push(minStack.top());// 不用更换栈顶元素        }        // 判断是否需要更新maxStack栈顶元素        if (maxStack.empty() || e > maxStack.top()) {            maxStack.push(e);// 入栈元素更大,更换栈顶元素        } else if (e <= maxStack.top()) {            maxStack.push(maxStack.top());// 不用更换栈顶元素        }    }    void pop() {// 新建MyStack数据结构的pop函数        // 三栈全部出栈        stacks.pop();        minStack.pop();        maxStack.pop();    }    int top() {        return stacks.top();    }     int getMin() {// O(1)时间返回最小值        return minStack.top();    }    int getMax() {// O(1)时间返回最大值        return maxStack.top();    }    private:    stack
stacks;// 存储栈 stack
minStack;// 最小值辅助栈 stack
maxStack;// 最大值辅助栈};

 

转载地址:http://gwozz.baihongyu.com/

你可能感兴趣的文章
nginx 开启ssl模块 [emerg] the “ssl“ parameter requires ngx_http_ssl_module in /usr/local/nginx
查看>>
Nginx 我们必须知道的那些事
查看>>
Nginx 源码完全注释(11)ngx_spinlock
查看>>
Nginx 的 proxy_pass 使用简介
查看>>
Nginx 的 SSL 模块安装
查看>>
Nginx 的优化思路,并解析网站防盗链
查看>>
Nginx 的配置文件中的 keepalive 介绍
查看>>
nginx 禁止以ip形式访问服务器
查看>>
Nginx 结合 consul 实现动态负载均衡
查看>>
Nginx 负载均衡与权重配置解析
查看>>
Nginx 负载均衡详解
查看>>
nginx 配置 单页面应用的解决方案
查看>>
nginx 配置https(一)—— 自签名证书
查看>>
nginx 配置~~~本身就是一个静态资源的服务器
查看>>
Nginx 配置服务器文件上传与下载
查看>>
Nginx 配置清单(一篇够用)
查看>>
Nginx 配置解析:从基础到高级应用指南
查看>>
Nginx 集成Zipkin服务链路追踪
查看>>
nginx 集群配置方式 静态文件处理
查看>>
nginx+php的搭建
查看>>