[LeetCode] 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.

Example:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> Returns -3.
minStack.pop();
minStack.top();      --> Returns 0.
minStack.getMin();   --> Returns -2.

設計一個最小棧,實現push, pop, top, getMin四個功能。相比原來的棧多了一個功能,可以返回當前棧內的最小值。

解法1:使用2個棧,棧1記錄進來的數,棧2記錄目前的最小值。當有新數push進來的時候,如果棧2為空或者這個數小於棧2頂上的值,就把這個數推入棧2。當pop的數正好等於最小值時,說明當前棧內的最小值變化了,要彈出這個最小值,記錄的下一個最小值來到棧頂。

解法2:只使用1個棧,用一個變量min_val記錄當前的最小值,將當前最小值一同入棧,為節省空間,僅在當前最小值更改時才入棧。所以該棧的push和pop實際上可能是兩次。當新進來的數小於min_val時,把當前的min_val和新進來的數一起推入到棧,min_val變為這個新進來的數。當pop棧頂元素的時候,如果棧頂元素的值和min_val相等,那么就把它下面記錄的之前最小值賦給min_val並彈出。

解法3:也是使用1個棧,但棧中存的是當前值與最小值的差,用一個元素來記錄,然后根據這個值可以計算出當前值和最小值。當棧頂元素為正時,表示當前元素比最小元素大,當前值為最小值+差值;當棧頂元素為負時,其表示的是當前元素值比之前最小值小,現在的最小值就是元素值。

要注意重復值的push和pop。

Java: 2 Stacks

public class MinStack {
    private Stack<Integer> stack;
    private Stack<Integer> minStack;

    public MinStack() {
        stack = new Stack<Integer>();
        minStack = new Stack<Integer>();
    }

    public void push(int number) {
        stack.push(number);
        if (minStack.empty() || minStack.peek >= number)
            minStack.push(number);
    }

    public int pop() {
        if (stack.peek().equals(minStack.peek()) ) 
            minStack.pop();
        return stack.pop();
    }

    public int min() {
        return minStack.peek();
    }
}

Java: 2 Stacks

public class MinStack {
    private Stack<Integer> s1 = new Stack<>();
    private Stack<Integer> s2 = new Stack<>();
    
    /** initialize your data structure here. */
    public MinStack() {}
    
    public void push(int x) {
        s1.push(x);
        if (s2.isEmpty() || s2.peek() >= x) s2.push(x);
    }
    
    public void pop() {
        // Cannot write like the following:
        // if (s2.peek() == s1.peek()) s2.pop();
        // s1.pop();
        int x = s1.pop();
        if (s2.peek() == x) s2.pop();
    }
    
    public int top() {
        return s1.peek();
    }
    
    public int getMin() {
        return s2.peek();
    }
}

Java: 1 Stack

public class MinStack {
    private int min_val = Integer.MAX_VALUE;
    private Stack<Integer> s = new Stack<>();
    
    /** initialize your data structure here. */
    public MinStack() {}
    
    public void push(int x) {
        if (x <= min_val) {
            s.push(min_val);
            min_val = x;
        }
        s.push(x);
    }
    
    public void pop() {
        if (s.pop() == min_val) min_val = s.pop();
    }
    
    public int top() {
        return s.peek();
    }
    
    public int getMin() {
        return min_val;
    }
}

Python: 2 Stacks

class MinStack:
  def __init__(self):
    self.stack = []
    self.minStack = []

  def push(self, x):
    self.stack.append(x)
    if len(self.minStack) == 0 or x <= self.minStack[-1]:
      self.minStack.append(x)

  def pop(self):
    if self.top() == self.getMin():
        self.minStack.pop()
    return self.stack.pop()

  def top(self):
    return self.stack[-1]

  def getMin(self):
    return self.minStack[-1]  

Python: 1 Stack,最小值和元素一同入棧

class MinStack(object):

    def __init__(self):
        self.min = 2147483647
        self.stack = []

    def push(self, x):
        if x <= self.min:
            self.stack.append(self.min)
            self.min = x
        self.stack.append(x)

    def pop(self):
        peak = self.stack.pop()
        if peak == self.min:
            self.min = self.stack.pop()

    def top(self):
        return self.stack[-1]

    def getMin(self):
        return self.min

Python: 1 Stack,記錄差值

class MinStack(object):

    def __init__(self):
        self.min = 2147483648
        self.stack = []

    def push(self, x):  
        if not self.stack:
            self.min = x
        self.stack.append(x - self.min)
        if x < self.min:
            self.min = x

    def pop(self):
        peak = self.stack.pop()
        if peak < 0:
            self.min = self.min - peak

    def top(self):
        if self.stack[-1] < 0:
            return self.min
        else:
            return self.min + self.stack[-1]

    def getMin(self):
        return self.min

C++: 2 Stacks

class MinStack {
public:
    /** initialize your data structure here. */
    MinStack() {}
    
    void push(int x) {
        s1.push(x);
        if (s2.empty() || x <= s2.top()) s2.push(x);
    }
    
    void pop() {
        if (s1.top() == s2.top()) s2.pop();
        s1.pop();
    }
    
    int top() {
        return s1.top();
    }
    
    int getMin() {
        return s2.top();
    }
    
private:
    stack<int> s1, s2;
};

C++: 1 Stack

class MinStack {
public:
    /** initialize your data structure here. */
    MinStack() {
        min_val = INT_MAX;
    }
    
    void push(int x) {
        if (x <= min_val) {
            st.push(min_val);
            min_val = x;
        }
        st.push(x);
    }
    
    void pop() {
        int t = st.top(); st.pop();
        if (t == min_val) {
            min_val = st.top(); st.pop();
        }
    }
    
    int top() {
        return st.top();
    }
    
    int getMin() {
        return min_val;
    }
private:
    int min_val;
    stack<int> st;
};

 

All LeetCode Questions List 題目匯總

  

  

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM