需要更好的阅读的体验请移步 👉 小牛肉的个人博客 👈
题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。
算法思想
该题难点在于最小元素min函数的写法,使用双栈法
使用一个栈按照大小顺序存储每次当前所有元素的最小值
比如:
stack1是普通的栈,完成正常操作。用stack2顺序存储最小值元素
-
初始状态
stack1 :
stack2: -
压入8:stack2为空,则直接压入
stack1 : 8
stack2: 8 -
压入 6:6 小于 stack2 的当前栈顶元素 8,则直接压入
stack1 : 8 6
stack2: 8 6 -
压入 5:5 小于 stack2 的当前栈顶元素 6,则直接压入
stack1 : 8 6 5
stack2: 8 6 5 -
压入 9:9 大于 stack2 的当前栈顶元素 5,不压入stack2
stack1 : 8 6 5 9
stack2: 8 6 5 -
压入 4:4 小于 stack2 的当前栈顶元素 5,则直接压入
stack1 : 8 6 5 9 4
stack2: 8 6 5 4
可以看到,当前栈顶的最小元素就是stack2的栈顶元素 4
-
出栈1次:stack2的栈顶元素4(当前所有元素的最小值)和stack1的栈顶元素 4 相同,则一并弹出,表示最小元素被更新了
stack1 : 8 6 5 9
stack2: 8 6 5
则当前栈中的最小值变为5 -
出栈2次:stack2的栈顶元素5(当前所有元素的最小值)和 stack1的栈顶元素不同,则只需弹出stack1的栈顶即可,说明当前所有元素的最小值不会因为9的弹出而改变,还是stack2的栈顶元素5
stack1 : 8 6 5
stack2: 8 6 5
则当前栈中的最小值还是5
具体代码
- C++
class Solution {
public:
//stack2用来有序排列stack1中的值,保证值从小到大排列(栈尾-》栈顶)
// 保证stack2中的栈顶始终是当前栈的最小值
stack<int> stack1, stack2;
void push(int value) {
stack1.push(value);
if(stack2.empty()) //如果顺序栈为空,则直接压入
stack2.push(value);
else if(value <= stack2.top()) //如果要压入的值小于当前顺序栈的栈顶,则压入
stack2.push(value);
}
void pop() {
// 如果要弹出的值和顺序栈的栈顶元素相同,则一并弹出
// 表示原先栈中的最小值随着本次弹出操作,原先的最小值被弹出来了
// 弹出原先的最小值后,当前顺序栈stack2的栈顶仍然是当前栈的最小值
if(stack1.top() == stack2.top())
stack2.pop();
stack1.pop();
}
int top() {
return stack1.top();
}
int min() {
return stack2.top();
}
};
- Java
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
if(stack2.empty())
stack2.push(node);
else if(node <= stack2.peek())
stack2.push(node);
}
public void pop() {
if(stack1.peek() == stack2.peek())
stack2.pop();
stack1.pop();
}
public int top() {
return stack1.peek();
}
public int min() {
return stack2.peek();
}
}