Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
You must implement a solution with O(1) time complexity for each function.
구현 해야할 기능
MinStack
: Stack 기능을 하면서 Stack 안의 최소값을 반환할 수 있는 Stack 구현void push(int val)
: val
값을 넣기void pop()
: 가장 최근에 넣은 값을 제거int top()
: 가장 최근에 넣은 값을 반환int getMin()
: MinStack
안의 최소값 반환Condition
기본 제공 코드
class MinStack {
public MinStack() {
}
public void push(int val) {
}
public void pop() {
}
public int top() {
}
public int getMin() {
}
}
기본 구현 전략
push(int val)
, pop()
, top()
은 기존 Stack을 이용하여 구현이 가능getMin()
을 time complexity O(1)으로 구현하는 것이 목표getMin()
구현 방법 : 내 하위의 element 중에서의 최소값을 가지는 Stack(subMin
)을 만듦, subMin
의 가장 위에 있는 값은 전체 element의 최소값을 나타내게 된다.구현 방법
Stack
을 이용해서 구현할 수 있다.Complexity
Stack
이용)public class MinStack {
private final Stack<Integer> values;
private final Stack<Integer> subMin;
public MinStack() {
this.values = new Stack<>();
this.subMin = new Stack<>();
}
public void push(int val) {
if (values.isEmpty()) {
values.add(val);
subMin.add(val);
return;
}
values.add(val);
subMin.add(Math.min(subMin.peek(), val));
}
public void pop() {
values.pop();
subMin.pop();
}
public int top() {
return values.peek();
}
public int getMin() {
return subMin.peek();
}
}
List
이용)class MinStack {
private final List<Integer> values;
private final List<Integer> mins;
private int topIndex;
public MinStack() {
this.values = new LinkedList<>();
this.mins = new LinkedList<>();
this.topIndex = -1;
}
public void push(int val) {
if (topIndex == -1) {
values.add(val);
mins.add(val);
topIndex++;
return;
}
values.add(val);
mins.add(Math.min(mins.get(topIndex), val));
topIndex++;
}
public void pop() {
values.remove(topIndex);
mins.remove(topIndex);
topIndex--;
}
public int top() {
return values.get(topIndex);
}
public int getMin() {
return mins.get(topIndex);
}
}
Array
이용)public class MinStack {
private static final int DEFAULT_SIZE = 32;
private int[] values;
private int[] subMin;
private int topIndex;
public MinStack() {
this.values = new int[DEFAULT_SIZE];
this.subMin = new int[DEFAULT_SIZE];
this.topIndex = -1;
}
public void push(int val) {
if (topIndex + 1 >= values.length) {
values = copyAndSizeDouble(values);
subMin = copyAndSizeDouble(subMin);
}
topIndex++;
values[topIndex] = val;
if (topIndex == 0) {
subMin[topIndex] = val;
return;
}
subMin[topIndex] = Math.min(val, subMin[topIndex - 1]);
}
public void pop() {
values[topIndex] = 0;
subMin[topIndex] = 0;
topIndex--;
}
public int top() {
return values[topIndex];
}
public int getMin() {
return subMin[topIndex];
}
private int[] copyAndSizeDouble(int[] array) {
int[] newArray = new int[array.length * 2];
for (int i = 0; i < array.length; i++) {
newArray[i] = array[i];
}
return newArray;
}
}