【剑指Offer面试编程题】题目1522:包含min函数的栈--九度OJ

题目描述:

定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

输入:

输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行为一个整数n(1<=n<=1000000), n代表将要输入的操作的步骤数。
接下来有n行,每行开始有一个字母Ci。
Ci=’s’时,接下有一个数字k,代表将k压入栈。
Ci=’o’时,弹出栈顶元素。

输出:

对应每个测试案例中的每个操作,
若栈不为空,输出相应的栈中最小元素。否则,输出NULL。

样例输入:

7
s 3
s 4
s 2
s 1
o
o
s 0
样例输出:

3
3
2
1
2
3
0
【解题思路】本题一个最笨的想法就是每次取出所有的栈中的元素然后输出其最小值,然后再从新压入栈,当然这也仅仅是第一反应而已,题目肯定不能这么去解。从最小元素和栈的特点出发,我们每次取的只能是栈顶的元素,那么是不是存在每次取的元素就是我们需要的元素呢,也就是说每次取出的元素都是当前状态下的最小元素。仔细思考一下,我们发现我们可以压栈的时候做文章,我们可以在每次压栈的时候,都压入当前栈状态下的最小元素。

   如何做到?若栈为空,但让栈的最小元素就是要压入的元素,直接压入,这个时候我们发现最小元素在栈顶。若栈非空,我们判断即将要压入的元素与栈顶元素(也就是当前栈中的最小元素)哪个小,我们压入小的那个,这样也确保当前栈的最小元素在栈顶。按照此规律压栈,我们能确保每次栈的最小元素在栈顶。

    输出的时候只需要取栈顶元素即可。

AC code:

#include <cstdio>
#include <stack>
#include <set>
#include <iterator>
using namespace std;
 
int main()
{
  int n;
  while(scanf("%d",&n)!=EOF)
  {
    char c[2];
    stack<int> stk;
    multiset<int> setk;
    for(int i=0;i<n;++i)
    {
      scanf("%s",c);
      if(c[0]=='s')
      {
        int tt;
        scanf("%d",&tt);
        stk.push(tt);
        setk.insert(tt);
      }else
      {
        if(!stk.empty())
        {
          multiset<int>::iterator it=setk.find(stk.top());
          setk.erase(it);
          stk.pop();
        }
      }
      if(!stk.empty())
        printf("%d
",*setk.begin());
      else
        printf("NULL
");
    }
  }
  return 0;
}
/**************************************************************
    Problem: 1522
    User: huo_yao
    Language: C++
    Result: Accepted
    Time:20 ms
    Memory:1188 kb
****************************************************************/
题目链接:http://ac.jobdu.com/problem.php?pid=1522

九度-剑指Offer习题全套答案下载:http://download.csdn.net/detail/huoyaotl123/8276299




原文地址:https://www.cnblogs.com/huoyao/p/4248900.html