问题
1 | Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. |
翻译:
设计一个栈,支持push、pop、top和在常量时间内检索最小元素。
push(x)——将元素x推入堆栈。
pop()——删除堆栈顶部的元素。
top()——获取top元素。
getMin()——检索堆栈中的最小元素。
例子:
MinStack = new MinStack();
minStack.push (2);
minStack.push (0);
minStack.push (3);
minStack.getMin ();- - >返回3。
minStack.pop ();
minStack.top ();- - >返回0。
minStack.getMin ();- - >返回2。
解题思路
本题是编写一个栈,但是对于栈的功能而言,多一个查询里面最小值的方法。栈的特点在于先进后出,我们可以用链表来实现。但是要获取最小值,
- 第一想到的就是可以通过遍历的方式来获取最小值,每次新进来一个对比一下就好。但是该方式在pop的时候就要重新定位最小值,还是比较耗性能的。
- 由于栈的特性,早先进去的值不会先被pop掉,所以在新增一个值,判断出最小值的时候,就是这一栈中最小的,即便被pop掉了,下一个节点的最小值是前面入栈中最小值,所以我们可以把最小值存入节点中。这样做就不需要遍历了
解题方法
按照遍历的方式:
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
50class MinStack {
private List<Integer> list = new ArrayList<>();
private Integer min = Integer.MAX_VALUE;
/**
* initialize your data structure here.
*/
public MinStack() {
}
public void push(int x) {
list.add(x);
if (x < min) {
min = x;
}
}
public void pop() {
if (list.size() <= 0) {
return;
}
Integer integer = list.remove(list.size() - 1);
if (integer.equals(min)) {
//重新遍历获取最小值
int min = Integer.MAX_VALUE;
for (Integer integer1 : list) {
if (min > integer1) {
min = integer1;
}
}
this.min = min;
}
}
public int top() {
if (list.size() <= 0) {
return 0;
}
return list.get(list.size() - 1);
}
public int getMin() {
return min;
}
}时间复杂度: 该方案用中,每一次的pop方式都需要遍历,所以为O(n)=O(n)
空间复杂度: 无
链表的方式实现:
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79class MinStack {
private Node indexNode;
/**
* initialize your data structure here.
*/
public MinStack() {
}
public void push(int x) {
Node node = new Node(x, x);
if (indexNode != null) {
//比较最小
if (indexNode.min < x) {
node.setMin(indexNode.min);
}
}
node.next = indexNode;
indexNode = node;
}
public void pop() {
indexNode = indexNode.next;
}
public int top() {
return indexNode.var;
}
public int getMin() {
return indexNode.min;
}
}
protected class Node {
private int var;
private int min;
private Node next;
public Node(int var, int min) {
this.var = var;
this.min = min;
}
public int getVar() {
return var;
}
public void setVar(int var) {
this.var = var;
}
public int getMin() {
return min;
}
public void setMin(int min) {
this.min = min;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}时间复杂度: 该方案用中,每一次的pop方式都需要遍历,所以为O(n)=O(1)
空间复杂度: 无
总结
本题的大致解法如上所诉,熟悉数据结构的特点,才能更好的编写代码。利用栈的先进后出保证前面的最小值不会因为pop而变化,如果是队列,那就不能用这种方式了。