-
题目描述:
-
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的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
最初的想法是添加一个成员变量存放最小的元素,每次压入一个新元素进栈的时候,如果该元素比当前最小的元素还要小,则更新最小元素。但是如果最小的元素弹出栈了,如何得到下一个最小的元素了??
这样我们的想法是使用一个辅助栈,保存最小值和次最小值。
首先往空的数据栈压入3,3是最小值,因此也将3压入辅助栈。接下来向数据栈压入4,4大于之前的最小值,因此我们仍然往辅助栈压入3.第三步向数据栈也如2,由于2小于之前的最小值3,因此最小值更新为2,并把2压入辅助栈。同样压入1时候,也要更新最小值,把1压入辅助栈。
思路是每次压入新的值时候,压入数据栈,如果辅助栈为空,也压入。如果不为空,则将该值与辅助栈的顶端比较,将两者中比较小的值压入辅助栈。
代码如下:
#include <stdio.h> #define MAX 100001 typedef struct stack{ int top; int data[MAX]; }sqStack; void initStack(sqStack *s){ s ->top = -1; } int isEmpty(sqStack *s){ if(s ->top == -1) return 0; else return -1; } void push(sqStack *s,int e){ s ->top ++; s ->data[s->top]=e; } int pop(sqStack *s){ int e; if(s ->top == -1) return NULL; if(s ->top != -1){ e = s ->data[s->top]; s->top--; } return e; } int getTop(sqStack *s,int *e){ if(isEmpty(s)==0) return -1; else if(isEmpty(s) == -1){ *e = s->data[s->top]; } return 0; } int main(){ sqStack m_data,m_min; int n,i,data,e; char c; while(scanf("%d",&n) != EOF){ initStack(&m_data); initStack(&m_min); for(i = 0;i < n;i++){ scanf("%1s",&c); if(c == 's'){ scanf("%d",&data); push(&m_data,data); if(isEmpty(&m_min)==0) push(&m_min,data); else if(isEmpty(&m_min)==-1){ getTop(&m_min,&e); if(data < e) push(&m_min,data); else push(&m_min,e); } }else if(c == 'o'){ if(isEmpty(&m_data)==-1&&isEmpty(&m_min)==-1){ pop(&m_data); pop(&m_min); } } if(getTop(&m_min,&e)==-1) printf("NULL\n"); else{ getTop(&m_min,&e); printf("%d\n",e); } } } return 0; }