定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
![在这里插入图片描述](https://img-blog.csdnimg.cn/04fc64f095124decb48ae882ca20b2df.png#pic_center)
方法一:辅助栈
要做出这道题目,首先要理解栈结构先进后出的性质。
对于栈来说,如果一个元素 a 在入栈时,栈里有其它的元素 b, c, d,那么无论这个栈在之后经历了什么操作,只要 a 在栈中,b, c, d 就一定在栈中,因为在 a 被弹出之前,b, c, d 不会被弹出。
因此,在操作过程中的任意一个时刻,只要栈顶的元素是 a,那么我们就可以确定栈里面现在的元素一定是 a, b, c, d。
那么,我们可以在每个元素 a 入栈时把当前栈的最小值 m 存储起来。在这之后无论何时,如果栈顶元素是 a,我们就可以直接返回存储的最小值 m。
按照上面的思路,我们只需要设计一个数据结构,使得每个元素 a 与其相应的最小值 m 时刻保持一一对应。因此我们可以使用一个辅助栈,与元素栈同步插入与删除,用于存储与每个元素对应的最小值。
当一个元素要入栈时,我们取当前辅助栈的栈顶存储的最小值,与当前元素比较得出最小值,将这个最小值插入辅助栈中;
当一个元素要出栈时,我们把辅助栈的栈顶元素也一并弹出;
在任意一个时刻,栈内元素的最小值就存储在辅助栈的栈顶元素中。
type MinStack struct {
s, minS []int
}
/** initialize your data structure here. */
func Constructor() MinStack {
return MinStack{}
}
func (this *MinStack) Push(x int) {
if len(this.minS) == 0 {
this.minS = append(this.minS, x)
} else {
top := this.minS[len(this.minS)-1]
if x < top {
top = x
}
this.minS = append(this.minS, top)
}
this.s = append(this.s, x)
}
func (this *MinStack) Pop() {
this.minS = this.minS[:len(this.minS)-1]
this.s = this.s[:len(this.s)-1]
}
func (this *MinStack) Top() int {
return this.s[len(this.s)-1]
}
func (this *MinStack) Min() int {
return this.minS[len(this.s)-1]
}
/**
* Your MinStack object will be instantiated and called as such:
* obj := Constructor();
* obj.Push(x);
* obj.Pop();
* param_3 := obj.Top();
* param_4 := obj.Min();
*/
list模拟栈
type pair struct {
val int
min int
}
type MinStack struct {
s *list.List
}
func Constructor() MinStack {
return MinStack{
s: list.New(),
}
}
func (this *MinStack) Push(x int) {
min := x
if this.s.Len() > 0 {
if this.s.Back().Value.(pair).min < min {
min = this.s.Back().Value.(pair).min
}
}
this.s.PushBack(pair{x, min})
}
func (this *MinStack) Pop() {
this.s.Remove(this.s.Back())
}
func (this *MinStack) Top() int {
return this.s.Back().Value.(pair).val
}
func (this *MinStack) Min() int {
return this.s.Back().Value.(pair).min
}