# 栈的最小值
栈结构如下所示,每次添加元素只能往顶部添加,取元素也只能从顶部先取元素。

实栈结构,且要求有以下四种方法:
push向顶部添加元素pop弹出顶部元素IsEmpty判断栈是否为空GetMin获取栈内的最小值(要求时间复杂度O(1))
# 思路

使用两个栈实现,一个栈存数据,另外一个栈存最小值
- 当栈需要插入数据时,判断插入的值是否小于
minStack栈顶的值,如果小于,则插入当前值到dataStack和minStack,否则dataStack插入数据,minStack则重复插入当前最小值 - 优化:可以不重复插入最小值,弹出元素的时候判断是否是最小值出栈,如果是的话
minStack才出栈
# 代码实现
package stack
// 之前实现的stack没有peek方法,在之前的stack上封装出peek方法用于查看栈顶部的值
func NewStackWithPeek() *StackWithPeek {
return &StackWithPeek{
Stack: NewStack(),
}
}
type StackWithPeek struct {
Stack
}
func (s *StackWithPeek)Peek() int {
if s.IsEmpty() {
panic("stack: use peek in empty stack!!!")
}
value := s.Pop()
s.Push(value)
return value.(int)
}
// 最小栈的实现
func NewMinStack() MinStack {
return MinStack{
dataStack: NewStackWithPeek(),
minStack: NewStackWithPeek(),
}
}
type MinStack struct {
dataStack *StackWithPeek
minStack *StackWithPeek
}
func (m *MinStack) Push(newNum int) {
if m.minStack.IsEmpty() {
m.minStack.Push(newNum)
} else if newNum <= m.GetMin() {
m.minStack.Push(newNum)
}
m.dataStack.Push(newNum)
}
func (m *MinStack) GetMin() int {
return m.minStack.Peek()
}
func (m *MinStack) IsEmpty() bool {
return m.dataStack.IsEmpty()
}
func (m *MinStack) Pop() int {
if m.IsEmpty() {
panic("stack: minstack can't pop!!!")
}
popValue := m.dataStack.Pop().(int)
if popValue == m.GetMin() {
m.minStack.Pop()
}
return popValue
}
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
示例代码:
func TestMinStack(t *testing.T) {
s := NewMinStack()
s.Push(18)
s.Push(4)
s.Push(2)
s.Push(19)
for !s.IsEmpty() {
fmt.Println(s.GetMin())
fmt.Println(s.Pop())
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
← 栈-1-栈 栈-3-两个队列实现栈 →