最小栈
https://leetcode-cn.com/problems/min-stack/
需求分析
- 需要完成栈的功能(压入、弹出),因此底层数据结构是栈
- 需要知道最小的元素;如果最小元素被弹出,需要知道第二小的元素
需求 2 是难点,由于需要知道第二小的元素,不能简单地用一个变量来记录最小值。
实现
使用 2 个栈。栈 A 是一般的栈,储存所有元素。使用一个辅助栈 B,存储栈 A 中所有 非严格降序 的元素,这样栈 B 顶就是最小的元素。
新元素 x
入栈时,如果 x <= B.top()
(x 小于 B 的栈顶),将 x 也压入栈 B,这样就保证了最小元素的更新。
要弹出栈 A 的元素时,检查这个元素是否是跟栈 B 顶的 元素相等。如果相等,栈 B 也需要弹出,这样栈 B 的栈顶就是第二小的元素了(有可能大小不变)。
由于 B 储存的是 非严格降序 的元素,即使 A 和 B 都压入了多个一样大小的最小值,也能保证弹出栈顶后维持正确的最小元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| type MinStack struct { stack []int descendingStack []int }
func Constructor() MinStack { return MinStack{make([]int, 0), make([]int, 0)} }
func (this *MinStack) Push(x int) { this.stack = append(this.stack, x) m := len(this.descendingStack) if m == 0 || x <= this.descendingStack[m-1] { this.descendingStack = append(this.descendingStack, x) } }
func (this *MinStack) Pop() { n, m := len(this.stack), len(this.descendingStack) if n == 0 { return }
x := this.stack[n-1] this.stack = this.stack[:n-1]
if x == this.descendingStack[m-1] { this.descendingStack = this.descendingStack[:m-1] } }
func (this *MinStack) Top() int { return this.stack[len(this.stack)-1] }
func (this *MinStack) GetMin() int { return this.descendingStack[len(this.descendingStack)-1] }
|