algorithm-base/animation-simulation/单调队列单调栈/最小栈.md
2023-05-07 11:18:42 +08:00

121 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈
>
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
>
> 另外希望手机阅读的同学可以来我的 <u>[**公众号:程序厨**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
#### [155. 最小栈](https://leetcode-cn.com/problems/min-stack/)
设计一个支持 push pop top 操作,并能在常数时间内检索到最小元素的栈。
- push(x) —— 将元素 x 推入栈中。
- pop() —— 删除栈顶的元素。
- top() —— 获取栈顶元素。
- getMin() —— 检索栈中的最小元素。
输入:
> ["MinStack","push","push","push","getMin","pop","top","getMin"] > [[],[-2],[0],[-3],[],[],[],[]]
输出:
> [null,null,null,null,-3,null,0,-2]
#### 题目解析
感觉这个题目的难度就在读懂题意上面读懂之后就没有什么难的了我们在上面的滑动窗口的最大值已经进行了详细描述其实这个题目和那个题目思路一致。该题让我们设计一个栈该栈具有的功能有pushpoptop 等操作,并且能够返回栈的最小值。比如此时栈中的元素为 5123。我们执行 getMin() ,则能够返回 1。这块是这个题目的精髓所在见下图。
![单调栈](https://cdn.jsdelivr.net/gh/tan45du/github.io.phonto2@master/myphoto/单调栈.46hlqk2xqza0.png)
我们一起先通过一个视频先看一下具体解题思路,通过视频一定可以整懂的,我们注意观察栈 B 内的元素。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210319162722440.gif)
我们来对视频进行解析 1.我们执行入栈操作时,先观察需要入栈的元素是否小于栈 B 的栈顶元素,如果小于则两个栈都执行入栈操作。
2.栈 B 的栈顶元素则是栈 A 此时的最小值。则 getMin() 只需返回栈 B 的栈顶元素即可。
3.出栈时,需要进行对比,若栈 A 和栈 B 栈顶元素相同,则同时出栈,出栈好 B 的栈顶保存的仍为此时栈 A 的最小元素
#### 题目代码
```java
class MinStack {
//初始化
Stack<Integer> A,B;
public MinStack() {
A = new Stack<>();
B = new Stack<>();
}
//入栈,如果插入值,当前插入值小于栈顶元素,则入栈,栈顶元素保存的则为当前栈的最小元素
public void push(int x) {
A.push(x);
if (B.isEmpty() || B.peek() >= x) {
B.push(x);
}
}
//出栈如果A出栈等于B栈顶元素则说明此时栈内的最小元素改变了。
//这里需要使用 equals() 代替 == 因为 Stack 中存储的是 int 的包装类 Integer
public void pop() {
if (A.pop().equals(B.peek()) ) {
B.pop();
}
}
//A栈的栈顶元素
public int top() {
return A.peek();
}
//B栈的栈顶元素
public int getMin() {
return B.peek();
}
}
```
GO Code:
```go
type MinStack struct {
stack []int
minStk []int
}
/** initialize your data structure here. */
func Constructor() MinStack {
return MinStack{
stack: []int{},
minStk: []int{},
}
}
// Push 入栈,如果插入值,当前插入值小于栈顶元素,则入栈,栈顶元素保存的则为当前栈的最小元素
func (m *MinStack) Push(x int) {
m.stack = append(m.stack, x)
if len(m.minStk) == 0 || m.minStk[len(m.minStk) - 1] >= x {
m.minStk = append(m.minStk, x)
}
}
// Pop 出栈如果stack出栈等于minStk栈顶元素则说明此时栈内的最小元素改变了。
func (m *MinStack) Pop() {
temp := m.stack[len(m.stack) - 1]
m.stack = m.stack[: len(m.stack) - 1]
if temp == m.minStk[len(m.minStk) - 1] {
m.minStk = m.minStk[: len(m.minStk) - 1]
}
}
// Top stack的栈顶元素
func (m *MinStack) Top() int {
return m.stack[len(m.stack) - 1]
}
// GetMin minStk的栈顶元素
func (m *MinStack) GetMin() int {
return m.minStk[len(m.minStk) - 1]
}
```
###