Leetcode:155. Min Stack
阿新 • • 發佈:2018-12-13
分析
利用一個LinkedList 連結串列儲存資料,類似於鏈stack, 還有陣列stack 採用ArrayList儲存 關於如何查詢最小元素的情況
思路一
最原始的方法:每次遍歷儲存元素的情況 ,時間複雜度為O(n)
程式碼
package data_struture;
import java.util.LinkedList;
import java.util.List;
/**
* 155. Min Stack
* Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
*
* push(x) -- Push element x onto stack.
* pop() -- Removes the element on top of the stack.
* top() -- Get the top element.
* getMin() -- Retrieve the minimum element in the stack.
*/
public class MinStack {
//建構函式情況
private List<Integer> store;
public MinStack(){
store = new LinkedList<>();
}
//壓入stack
public void push(int x){
this.store.add(x);
}
//彈出stack頂部的元素,刪除
public void pop(){
this.store.remove(store. size() - 1);
}
//返回stack頂部的元素情況,不刪除
public int top(){
return this.store.get(store.size()-1);
}
public int getMin() {
//產生每次對
int min= Integer.MAX_VALUE;
for (Integer i : store) {
if (i < min) {
min = i;
}
}
return min;
}
public static void main(String[] args) {
MinStack test =new MinStack();
test.push(-2);
test.push(0);
test.push(-3);
System.out.println(test.getMin());
test.pop();
System.out.println(test.top());
System.out.println(test.store.size());
System.out.println(test.getMin());
}
}
思路二:two stack
使用一個min, 記錄stack中的最小值,但是也帶來了問題,如果最小元素出stack後如何找到下一個最小的元素? 所以還是沒有解決該問題 不容易想到用兩個棧來儲存資料,一個用於正常的儲存棧資料,,另一個用於儲存前一個棧的最小值。 一個stack儲存真正的元素,另一min_stack記錄最小元素的情況 上述min_stack儲存的也是真正的元素情況, ** 當加入一個元素時,有兩種情況下要加入min_stack**
- 第一次加入 元素,此時min_stack.isEmpty()==true;
- 當min_stack.peek()>=x時
程式碼
class MinStack {
stack<int> s;
stack<int> trackMin;
public:
void push(int x) {
if(trackMin.empty() || x<=trackMin.top())
trackMin.push(x);
s.push(x);
}
void pop() {
if(s.empty()) return;
if(s.top()==trackMin.top())
trackMin.pop();
s.pop();
}
int top() {
return s.top();
}
int getMin() {
return trackMin.top();
}
};
終極思路
如何設計一個時間複雜度為O(1),空間複雜度為O(1), 只使用一個stack的情況,減少使用一個stack 的情況, stack 不是儲存真實壓入的資料,minfile 是儲存真實的最小資料情況 回到原來的思路: 採用一個stack記錄資料,minfile記錄最小值情況
push
假設要插入的是x , minfile 是最小資料情況
- 如果stack為空,是第一次插入資料情況,則直接插入, stack.push(x), min = x;
- 如果stack 不為空, - 判斷 x 與min 的大小情況, - 如果 x>=min 的話, 對最小值沒有影響,直接插入即可,也不用更新min - 如果 x<min 的話, stack.push(2 * x - min ), 然後讓 min =x ; 比如最小值為3, 現在新=2,2小於 3, 所以插入 2* 2-3 =1, 更新min =2;
pop
int y =stack.peek()
- 如果y 大於或者等於 premin, 說明min 還在stack 中, 所以直接stack.pop() 後即可
- 如果y 小於 min, 那麼說明真在的y 是 min, 直接返回 min然後 更新 min , min = 2 * premin- y,
總結
如果stack.peek < min , 那麼原來的資料其實就是min ,真正要壓入的資料,
說白了就是對資料進行一定程度對變換即可,加密和揭祕過程,如果是stack.peek()>min, 或者x>=min , 直接插入即可,
當x<min ,才需要正在當更新整個資料當過程
**x 代表入stack, y 代表出stack, 即使 stack.peek() 使用這個兩個元素與min, 進行一定程度對比較即可 如果 x <min ,需要進行加密壓入,同時更新min 如果 y<min, 需要進行解密彈出, 同時更新min **
package data_struture;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
/**
* 155. Min Stack
* Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
*
* push(x) -- Push element x onto stack.
* pop() -- Removes the element on top of the stack.
* top() -- Get the top element.
* getMin() -- Retrieve the minimum element in the stack. 要求使用
*/
public class MinStack {
//建構函式情況
private int min;
private Stack<Integer> stack;
public MinStack() {
stack = new Stack<>();
}
//壓入stack
public void push(int x) {
//第一次處理整個元素當情況
if (stack.isEmpty()) {
min = x;
stack.push(x);
}
//x<min 所以需要進行加密
if (x < min) {
min = x;
stack.push(2 * x - min);
} else {
stack.push(x);
}
}
//彈出stack頂部的元素,刪除
public void pop() {
if (stack.isEmpty()) {
System.out.println("Stack is empty");
return;
}
System.out.print("Top Most Element Removed: ");
int y = stack.peek();
//需要揭祕
if (y < min) {
System.out.println(min);
min = 2 * min - y;
} else {
System.out.println(y);
}
}
//返回stack頂部的元素情況,不刪除
public int top() {
if (stack.isEmpty()) {
System.out.println("Stack is empty ");
return -1;
}
Integer y = stack.peek();
System.out.println("Top Most Element is: ");
if (y >= min) {
return y;
} else {
return min;
}
}
public int getMin() {
if (stack.isEmpty()) {
System.out.println("stack is empty");
return -1;
}
return min;
}
public static void main(String[] args) {
MinStack test =new MinStack();
test.push(-2);
test.push(0);
test.push(-3);
System.out.println(test.getMin());
test.pop();
System.out.println(test.top());
System.out.println(test.stack.size());
System.out.println(test.getMin());
}
}