解法一:双栈
这道题的关键就是,每个元素入栈时,还要记下来当前栈中的最小值。可以用一个额外的栈 minStk 来记录栈中每个元素入栈时的栈中的最小元素是多少,放在栈顶,这样每次删除元素后,就能快速得到剩余栈中的最小元素了。
type MinStack struct {
valStack []int // 记录栈中所有元素
minStack []int // 记录栈中每个元素入栈时的栈中的最小元素是多少,因此两个栈长度一样
}
func Constructor() MinStack {
return MinStack{
valStack: make([]int, 0),
minStack: make([]int, 0),
}
}
func (this *MinStack) Push(val int) {
this.valStack = append(this.valStack, val)
// 维护 minStk 栈顶为全栈最小元素
if len(this.minStack) == 0 || val < this.minStack[len(this.minStack)-1]{
this.minStack = append(this.minStack, val)
}else {
this.minStack = append(this.minStack, this.minStack[len(this.minStack)-1])
}
}
func (this *MinStack) Pop() {
if len(this.valStack) > 0{
this.valStack = this.valStack[:len(this.valStack)-1]
}
if len(this.minStack) > 0{
this.minStack = this.minStack[:len(this.minStack)-1]
}
}
func (this *MinStack) Top() int {
return this.valStack[len(this.valStack)-1]
}
func (this *MinStack) GetMin() int {
return this.minStack[len(this.minStack)-1]
}
minStack的空间可以进一步优化,不需要保持和valStack等长
type MinStack struct {
valStack []int // 记录栈中所有元素
minStack []int // 栈顶记录当前最小的元素
}
func Constructor() MinStack {
return MinStack{
valStack: make([]int, 0),
minStack: make([]int, 0),
}
}
func (this *MinStack) Push(val int) {
this.valStack = append(this.valStack, val)
// 维护 minStk 栈顶为全栈最小元素,注意这里要判断val <= 栈顶元素,因为可能最小元素有多个重复值
if len(this.minStack) == 0 || val <= this.minStack[len(this.minStack)-1]{
this.minStack = append(this.minStack, val)
}
}
func (this *MinStack) Pop() {
if len(this.valStack) > 0{
tmp := this.valStack[len(this.valStack)-1]
if tmp == this.minStack[len(this.minStack)-1]{ // 弹出的刚好是当前最小元素
this.minStack = this.minStack[:len(this.minStack)-1] // 更新栈顶元素
}
this.valStack = this.valStack[:len(this.valStack)-1]
}
}
func (this *MinStack) Top() int {
if len(this.valStack) > 0{
return this.valStack[len(this.valStack)-1]
}
return -1
}
func (this *MinStack) GetMin() int {
if len(this.minStack) > 0{
return this.minStack[len(this.minStack)-1]
}
return -1
}
/**
* Your MinStack object will be instantiated and called as such:
* obj := Constructor();
* obj.Push(val);
* obj.Pop();
* param_3 := obj.Top();
* param_4 := obj.GetMin();
*/