leetcode-Min Stack

一共用两个栈。一个栈elements用来放所有数据,另一个栈mins专门用来存放最小值。入栈时所有元素都能加入elements栈,但只有当前元素小于等于mins栈的栈顶元素时才能加入mins栈。

 1 class MinStack {
 2 public:
 3     void push(int x) {
 4         elements.push(x);
 5         if (mins.empty()||x<=mins.top())
 6             mins.push(x);
 7     }
 8 
 9     void pop() {
10         if (elements.empty()) return;
11         if (elements.top() == mins.top())
12             mins.pop();
13         elements.pop();
14     }
15 
16     int top() {
17         return elements.top();
18     }
19 
20     int getMin() {
21         return mins.top();
22     }
23 private:
24     stack<int> elements;
25     stack<int> mins;
26 };

 

==================================================================================

http://leetcode.com/2010/11/stack-that-supports-push-pop-and-getmin.html

Design a stack that supports push, pop, and retrieving the minimum element in constant time. Can you do this?


Today, I read this interesting problem (exercise 4-44) from the excellent book “The Algorithm Design Manual” by Steven Skiena.

Initially I thought of using an extra min-heap to store the elements. Although this enables us to retrieve the minimum element in O(1), push and pop operations both operates in O(lg N), where N is the total number of elements in the stack. Definitely not a desirable method.

How about recording the current minimum in the stack? This works until you pop current minimum off the stack, where you would have to update your next minimum, which takes O(N) time to examine all elements.

Hint:
Assume you have an extra stack. What would you do with the extra stack?

Stack is a last in, first out (LIFO) data structure. It can be easily implemented either through an array or a linked list.

Solution:
The solution is surprisingly simple and elegant — Use an extra stack to maintain the minimums. What does this mean?

  • To retrieve the current minimum, just return the top element from minimum stack.
  • Each time you perform a push operation, check if the pushed element is a new minimum. If it is, push it to the minimum stack too.
  • When you perform a pop operation, check if the popped element is the same as the current minimum. If it is, pop it off the minimum stack too.

All of the above operates in O(1) constant time.

A Gotcha:

There is one small gotcha I purposely left in the above solution. Could you figure it out without looking at the code below first?

 

 

Further Thoughts:

Before we conclude this section, try a variation of this problem (appeared as a Google interview question):

Design a queue that supports push_rear, pop_front, and get_min in O(1). Would that be elegantly possible too?

 

Hint:
Use two queues.

If you need extra hints, see this post (both problems are related). If you could design a queue with push_rear, pop_front, and get_min in O(1), then finding the Sliding Window Maximum could be solved by direct application of such data structure.

posted @ 2014-11-10 18:04  Ryan in C++  阅读(2056)  评论(0编辑  收藏  举报