转载请注明出处:http://blog.csdn.net/ns_code/article/details/22211943
题目:
How would you design a stack which, in addition to push and pop, also has a function min which returns the minimum element? Push, pop and min should all operate in O(1) time.
翻译:
要求实现一个栈,除了有push和pop操作外,还有一个min函数返回栈中的最小值, push,pop和min函数的时间复杂度都要为O(1)。
思路:
push和pop操作很明显就是O(1)的时间复杂度,关键是min函数,一般来说,我们求栈中的最小值,会从栈顶开始遍历栈,并设置一个变量Min来保存每次遍历时的最小值 ,遍历到比Min还小的元素,就将该元素赋给Min,但这种方法的时间复杂度为O(n)。
我们可以考虑用空间换时间的思想来提高时间复杂度(很多时候时空均衡都是提高时间复杂度的常规思路),我们另外可以设置一个同样最大深度的栈来保存对应序列的最小值。比如,我们以数组来模拟栈,假设栈A的最大深度为100,目前深度为10,我们就可以另外建立一个栈B,也设它的最大深度为100,另外,让B的前10个元素保存对应位置到栈底位置间元素的最小值,比如,B[3]保存A[3]、A[2]、A[1]、A[0]这几个元素中的最小值,B[2]保存A[2]、A[1]、A[0]这几个元素中的最小值....B[0]则直接保存A[0]的值。这样,我们求栈的最小元素时,直接返回B数组中对应位置的元素值即可。
实现代码:
/**************************************************** 题目描述: 实现一个栈的push、pop操作和min操作(返回栈中最小值), 要求push,pop和min函数的时间复杂度都为O(1) Date:2014-03-26 *****************************************************/ /* 本程序采用数组模拟栈 */ typedef int ElemType; #define MAX 100 //栈的深度 #include<stdio.h> /* 在栈顶索引指针为top时,向栈A中压入数据data */ bool push(int *A,int &top,ElemType data) { if(top>=MAX-1 || top<-1) return false; A[++top] = data; return true; } /* 在栈顶索引指针为top时,出栈 */ bool pop(int &top) { if(top<0) return false; top--; return true; } /* 栈顶当前索引指针为top,Min数组最大深度也为MAX, 且Min的有效元素数与栈A中的元素个数相同, 它的对应位置用来保存栈A对应位置到栈底这一部分元素中的最小值 */ void minAll(int *A,int *Min,int top) { if(top>MAX-1) return ; Min[0] = A[0]; int i; for(i=1;i<=top;i++) { if(Min[i-1] > A[i]) Min[i] = A[i]; else Min[i] = Min[i-1]; } } /* 返回栈顶为top时栈中元素的最小值 */ int min(int *Min,int top) { return Min[top]; } int main() { int A[MAX]; int top = -1; push(A,top,4); push(A,top,7); push(A,top,2); push(A,top,6); push(A,top,3); push(A,top,8); push(A,top,5); push(A,top,1); int Min[MAX]; minAll(A,Min,7); int i; for(i=0;i<=top;i++) printf("%d ",Min[i]); printf("\n"); /* int min7 = min(Min,7); printf("%d\n",min7); pop(top); int min6 = min(Min,6); printf("%d\n",min6); */ return 0; }测试结果:
注:代码开源到我的Github:https://github.com/mmc-maodun/CareerCup