LeetCode算法题-Min Stack(Java实现)
这是悦乐书的第177次更新,第179篇原创
01 看题和准备
今天介绍的是LeetCode算法题中Easy级别的第36题(顺位题号是155)。设计一个支持push,pop,top和在恒定时间内检索最小元素的堆栈。
push(x) - 将元素x推入堆栈。
pop() - 删除堆栈顶部的元素。
top() - 获取顶部元素。
getMin() - 检索堆栈中的最小元素。
例如:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); - >返回-3。
minStack.pop();
minStack.top(); - >返回0。
minStack.getMin(); - >返回-2。
本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。
02 第一种解法
利用整型数组和ArrayList作为栈。
入栈的时候,创建一个容量为2的数组,数组第一个元素是要入栈的元素,第二个元素是最小值,将数组添加到list中。
出栈的时候,获取list的最后一个元素,并将其移除,此时的最小值是list最后一位元素(数组)的第二个值。
获取栈顶,即是list中最后一位元素(数组)的第一个值。
最小值直接返回最小值即可。
class MinStack {
private List<int[]> stack ;
private int min ;
public MinStack() {
stack = new ArrayList<int[]>();
}
public void push(int x) {
int[] arr = new int[2];
arr[0] = x;
arr[1] = stack.isEmpty() ? x : Math.min(x, min);
min = arr[1];
stack.add(arr);
}
public void pop() {
if (!stack.isEmpty()) {
stack.remove(stack.size()-1);
min = stack.isEmpty() ? 0 : stack.get(stack.size()-1)[1];
}
}
public int top() {
return stack.get(stack.size()-1)[0];
}
public int getMin() {
return min;
}
}
03 第二种解法
此解法使用了栈本身和优先队列两种结构,优先队列是为了解决最小值的问题。
入栈、出栈、栈顶这些操作都可以用栈本身的方法,而最小值则是优先队列的头部元素,因为优先队列自带排序算法,在初始化时如果不指定排序方式,则默认以自然方式排序。所以在入栈时,一并也将元素放入优先队列中,而最小值就是队列的头部元素,而其他元素的顺序是不是按升序依次排列的,这个还真不一定,但是如果你通过实现Comparable接口,重写其compareTo方法,可以按照自己定义的方式来排序。
class MinStack2 {
PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();
Stack<Integer> stack = new Stack<Integer>();
public MinStack2() {}
public void push(int x) {
pQueue.add(x);
stack.push(x);
}
public void pop() {
int trmp = stack.pop();
pQueue.remove(trmp);
}
public int top() {
return stack.peek();
}
public int getMin() {
return pQueue.peek();
}
}
04 第三种解法
使用两个栈,一个作为正常的栈进行入栈、出栈、获取栈顶操作,另外一个栈则存储最小值,每次在第一个栈进行入栈和出栈操作时,都要进行判断,对第二个栈中的最小值进行相应的操作。
class MinStack3 {
private Stack<Integer> s1 = new Stack<>();
private Stack<Integer> s2 = new Stack<>();
public MinStack3() {}
public void push(int x) {
s1.push(x);
if (s2.isEmpty() || s2.peek() >= x) {
s2.push(x);
}
}
public void pop() {
int x = s1.pop();
if (s2.peek() == x) s2.pop();
}
public int top() {
return s1.peek();
}
public int getMin() {
return s2.peek();
}
}
05 第四种解法
较之第三种解法,此解法只使用了一个栈来完成入栈、出栈、获取栈顶和最小值的全部操作。
入栈时,如果新入栈的元素比最小值小,那么要将旧的最小值入栈,并且新的最小值是此时新入栈的元素,最后再将新元素入栈。
出栈时,如果要移除的元素正好是当前最小值,那么就需要再出栈一次,并且最小值等于第二次出栈要移除的值,因为入栈时是会将旧的最小值添加进去的,所以出栈时要做此判断。
class MinStack4 {
int min = Integer.MAX_VALUE;
Stack<Integer> stack = new Stack<Integer>();
public void push(int x) {
if(x <= min){
stack.push(min);
min = x;
}
stack.push(x);
}
public void pop() {
if(stack.pop() == min) {
min=stack.pop();
}
}
public int top() {
return stack.peek();
}
public int getMin() {
return min;
}
}
06 小结
算法专题目前已连续日更超过一个月,算法题文章35+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。
以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!
LeetCode算法题-Min Stack(Java实现)的更多相关文章
- LeetCode算法题-Min Cost Climbing Stairs(Java实现)
这是悦乐书的第307次更新,第327篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第176题(顺位题号是746).在楼梯上,第i步有一些非负成本成本[i]分配(0索引). ...
- LeetCode算法题-Heaters(Java实现)
这是悦乐书的第239次更新,第252篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第106题(顺位题号是475).冬天来了!您在比赛期间的第一份工作是设计一个固定温暖半径 ...
- LeetCode算法题-Implement Stack Using Queues
这是悦乐书的第193次更新,第198篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第54题(顺位题号是225).使用队列实现栈的以下操作: push(x) - 将元素x推 ...
- LeetCode算法题-Sqrt(Java实现)
这是悦乐书的第158次更新,第160篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第17题(顺位题号是69). 计算并返回x的平方根,其中x保证为非负整数. 由于返回类型 ...
- LeetCode算法题-Minimum Distance Between BST Nodes(Java实现-四种解法)
这是悦乐书的第314次更新,第335篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第183题(顺位题号是783).给定具有根节点值的二叉搜索树(BST),返回树中任何两个 ...
- LeetCode算法题-Second Minimum Node In a Binary Tree(Java实现)
这是悦乐书的第285次更新,第302篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第153题(顺位题号是671).给定非空的特殊二叉树,其由具有非负值的节点组成,其中该树 ...
- LeetCode算法题-Minimum Absolute Difference in BST(Java实现)
这是悦乐书的第253次更新,第266篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第120题(顺位题号是530).给定具有非负值的二叉搜索树,找到任意两个节点的值之间的最 ...
- LeetCode算法题-Degree of an Array(Java实现)
这是悦乐书的第294次更新,第312篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第162题(顺位题号是697).给定一个由正整数组成的非空数组,该数组的度数被定义为任意 ...
- LeetCode算法题-Count Binary Substrings(Java实现)
这是悦乐书的第293次更新,第311篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第161题(顺位题号是696).给定一个字符串s,计算具有相同数字0和1的非空且连续子串 ...
随机推荐
- OpenCV入门之获取验证码的单个字符(字符切割)
介绍 在我们日常上网注册账号以及制作网络爬虫时,经常会遇到奇奇怪怪的验证码,有些容易,有些连人眼都无法辨识.于是,大牛们想到了用深度学习的方法来破解验证码,对于一般的验证码往往能出奇制胜,取得不俗 ...
- NPOI导出EXCEL报_服务器无法在发送 HTTP 标头之后追加标头
虽然发表了2篇关于NPOI导出EXCEL的文章,但是最近再次使用的时候,把以前的代码粘贴过来,居然报了一个错误: “服务器无法在发送 HTTP 标头之后追加标头” 后来也查询了很多其他同学的文章,都没 ...
- WPF 水平进度条
WPF设计界面过程中,有时需要设计一种可以手动滑动修改并实时显示的进度条 进度条,效果如下: 颜色.图标.节点什么的,都可以重新替换. 前端XAML代码: <UserControl x:Clas ...
- .NET MVC JSON JavaScriptSerializer 字符串的长度超过 maxJsonLength 值问题的解决
[ArgumentException: 使用 JSON JavaScriptSerializer 序列化或还原序列化期间发生错误.字符串的长度超过在 maxJsonLength 属性上设定的值. 参数 ...
- C#中设置窗口在最前显示而其他窗口不能使用
对程序中的一个Form1处理,让其在打开的情况下,其他窗体都无法使用,全部焦点都在他身上. 1.这种方法最简单,直接调用窗体的模态对话框函数显示窗体 Form1.ShowDialog(): 2.设置窗 ...
- SpringBoot零XML配置的Spring Boot Application
Spring Boot 提供了一种统一的方式来管理应用的配置,允许开发人员使用属性properties文件.YAML 文件.环境变量和命令行参数来定义优先级不同的配置值.零XML配置的Spring B ...
- Netty实战九之单元测试
ChannelHandler是Netty应用程序的关键元素,所以彻底地测试他们应该是你的开发过程的一个标准部分.最佳实践要求你的测试不仅要能够证明你的实现是正确的,而且还要能够很容易地隔离那些因修改代 ...
- python中的eval函数
eval() 函数十分强大 -- 将字符串 当成 有效的表达式 来求值 并 返回计算结果 In [1]: eval("1 + 3") Out[1]: 4 In [2]: eval( ...
- Java 中变量初始化、子类和父类构造器调用的顺序
先说结论 变量初始化 -> 父类构造器 -> 子类构造器 贴代码 Animcal.java 父类 public class Animal { private static int inde ...
- JavaScript字符串转换为数字
今天在工作中碰到了一个问题,要将字符串转换为数字,否则函数不能正常工作, 特地研究了下,写了2个函数,供大家参考,代码如下: /** * 将字符串转换为数字 * @param {Object} str ...