概览:
力扣155. 最小栈
设计一个支持 push
,pop
,top
操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack
类:
MinStack()
初始化堆栈对象。void push(int val)
将元素val推入堆栈。void pop()
删除堆栈顶部的元素。int top()
获取堆栈顶部的元素。int getMin()
获取堆栈中的最小元素。
示例 1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
提示:
-231 <= val <= 231 - 1
pop
、top
和getMin
操作总是在 非空栈 上调用push
,pop
,top
, andgetMin
最多被调用3 * 104
次
解法:自己尝试写的
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
class MinStack {
int min;
int[] stack;
int size;
public MinStack() {
stack = new int[30000];
size = 0;
}
public void push(int val) {
if (size == 0) {
min = val;
} else {
min = min < val ? min : val;
}
stack[size++] = val;
}
public void pop() {
if (size == 1) {
size--;
return;
}
min = stack[size - 2];
size--;
for (int i = size - 1; i >= 0; i--) {
min = min < stack[i] ? min : stack[i];
}
}
public int top() {
return stack[size - 1];
}
public int getMin() {
return min;
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
解法2:最小栈
除了数据栈,单独另外准备一个栈,记录这个位置下栈的最小值。
例如:
数据栈:3,7,2,5,7(如果一直不pop的话)
最小栈:3,3,2,2,2
如果pop那么最小栈也要相应pop
代码1:Java内部Stack
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
class MinStack {
Stack<Integer> data;
Stack<Integer> min;
public MinStack() {
data = new Stack<>();
min = new Stack<>();
}
public void push(int x) {
data.push(x);
if (min.isEmpty() || min.peek() > x) {
min.push(x);
} else {
min.push(min.peek());
}
}
public void pop() {
data.pop();
min.pop();
}
public int top() {
return data.peek();
}
public int getMin() {
return min.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
实现2:数组实现栈
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
class MinStack {
int MAXN = 7500;//不断提交得到的
int[] data;
int[] min;
int size;
public MinStack() {
data = new int[MAXN];
min = new int[MAXN];
}
public void push(int x) {
data[size] = x;
if (size == 0 || min[size - 1] > x) {
min[size] = x;
} else {
min[size] = min[size - 1];
}
size++;
}
public void pop() {
size--;
}
public int top() {
return data[size - 1];
}
public int getMin() {
return min[size - 1];
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
所以,我打算看看那top3%到底是什么解法。
解法3:单链表实现栈
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
class MinStack {
class Node{
int val;
int minVal;
Node next;
public Node(int val, int minVal){
this.val = val;
this.minVal = minVal;
}
}
public Node preHead = new Node(-1, -1);
public MinStack() {
}
public void push(int val) {
Node node = new Node(val, val);
if (preHead.next != null && preHead.next.minVal < val){
node.minVal = preHead.next.minVal;
}
node.next = preHead.next;
preHead.next = node;
}
public void pop() {
preHead.next = preHead.next.next;
}
public int top() {
return preHead.next.val;
}
public int getMin() {
return preHead.next.minVal;
}
}
数据结构:使用单链表,每个节点 (Node) 包含:
- val:当前元素值
- minVal:截至该节点时的最小值
- next:指向下一个节点的指针
哨兵节点:preHead 作为头节点的前置节点,便于操作。