题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
理清思路
解题方法是双栈思想,主栈用于常规栈操作,辐栈用于保存每次入栈的最小元素。关键点在于入栈push和出栈pop,如下:
- 若主栈入栈后,主栈中只有一个元素,则也要同步将元素压入辐栈中。
- 若入主栈的元素小于等于辐栈的顶层元素,则也要同步将元素压入辐栈中。
- 若入主栈的元素大于辐栈的顶层元素,则只需将元素压入主栈中。
代码实现
- 构建整个栈结构
#define MAX_SIZE 20000
typedef struct {
int *mstack;//主栈:保存全部数值
int mtop;
int *astack;//辐栈:按顺序保存每次入栈的小值
int atop;
} MinStack;
- 在堆区中分配栈内存
MinStack* minStackCreate() {
MinStack *mystack;
mystack = (MinStack *)malloc(sizeof(MinStack));
if(mystack == NULL)
{
printf("Create my min stack error!\n");
return NULL;
}
mystack->mstack = (int *)malloc(sizeof(int)*MAX_SIZE);
if(mystack->mstack == NULL)
{
printf("Create my min stack 1 error!\n");
return NULL;
}
mystack->mtop = 0;
mystack->astack = (int *)malloc(sizeof(int)*MAX_SIZE);
if(mystack->astack == NULL)
{
printf("Create my min stack 2 error!\n");
return NULL;
}
mystack->atop = 0;
return mystack;
}
- 入栈push算法
void minStackPush(MinStack* obj, int x) {
if(obj->mtop < MAX_SIZE)
{
obj->mstack[obj->mtop] = x;
obj->mtop++;
if(obj->mtop == 1)//若主栈中只有一个元素,则将第一个元素压入辐栈
{
obj->astack[obj->atop] = x;
obj->atop++;
}
else if(x <= obj->astack[obj->atop - 1 ])//若元素小于等于辐栈中的顶层元素,则将元素压入辐栈
{
obj->astack[obj->atop] = x;
obj->atop++;
}
}
}
- 出栈pop算法
void minStackPop(MinStack* obj) {
int mpopval = 0;
int apopval = 0;
if(obj->mtop > 0)
{
mpopval = obj->mstack[obj->mtop - 1 ];
obj->mtop--;
apopval = obj->astack[obj->atop - 1];
if(mpopval == apopval)//若主栈出栈元素等于辐栈的顶层元素,则辐栈出栈
{
obj->atop--;
}
}
}
- 获取栈顶层元素
算法思想:返回主栈的顶层元素即可。
int minStackTop(MinStack* obj) {
int mreval = 0;
if(obj->mtop > 0)
{
mreval = obj->mstack[obj->mtop - 1 ];
}
return mreval;
}
- 获取栈中最小元素
算法思想:返回辐栈的顶层元素即可。
int minStackMin(MinStack* obj) {
int atopval = 0;
if(obj->atop > 0)
{
atopval = obj->astack[obj->atop - 1 ];
}
return atopval;
}
- 结束记得释放内存
void minStackFree(MinStack* obj) {
free(obj->mstack);
free(obj->astack);
free(obj);
}