1. 程式人生 > >Leetcode:155. Min Stack

Leetcode:155. Min Stack

分析

利用一個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());
    }
}