定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.
这道题无非比正常的栈多了一个返回栈中元素最小值的接口,一开始可能会觉得直接用一个min变量一直存着最小值不就行了吗,但是万一最小值在栈顶,然后被pop掉了呢?所以这种方法是行不通的
思路分析:
我们可以开辟一个辅助栈,里面从栈底到栈顶按照降序排列数据,如果入栈的元素小于辅助栈栈顶的元素,就将其同时放入原栈与辅助栈的栈顶,当然一开始栈为空时也是同时压栈;如果需要入栈的元素大于辅助栈栈顶的元素,就将原辅助栈栈顶的元素拷贝一份放入辅助栈栈顶
我们这么做的目的是让原栈和辅助栈可以一起pop,共用一个top及capacity
当出栈的元素是最小的元素时,刚好辅助栈栈顶的元素也是最小的元素;如果出栈的元素不是最小元素,则辅助栈栈顶已经拷贝了一份最小元素,同时与原栈一起出栈,辅助栈的栈顶还是最小元素,这样就方便了许多
如下图所示:以3->1->2的入栈顺序为例
3入栈时,为当前栈最小值,所以辅助栈也放入3;1入栈时,为当前栈最小值,所以1也被放入辅助栈;2入栈时,不是当前栈最小值,所以辅助栈复制一个1放入栈顶,以保证原栈和辅助栈能够同时完成出栈
代码:
typedef struct {
int capacity;
int top;
int* a;
int*min;
} MinStack;
/** initialize your data structure here. */
MinStack* minStackCreate() {
MinStack* tmp = (MinStack*)malloc(sizeof(MinStack));
tmp->capacity = 4;
tmp->top = 0;
tmp->a = (int*)malloc(sizeof(int) * tmp->capacity);
tmp->min = (int*)malloc(sizeof(int) * tmp->capacity);
return tmp;
}
void minStackPush(MinStack* obj, int x) {
if (obj->top == obj->capacity)//判断两栈是否需要扩容
{
int*tmp1 = (int*)realloc(obj->a, 2*obj->capacity*sizeof(int));
int*tmp2 = (int*)realloc(obj->min, 2*obj->capacity*sizeof(int));
if (tmp1 == NULL || tmp2 == NULL)
{
perror("realloc");
minStackFree(obj);
}
else
{
obj->a = tmp1;
obj->min = tmp2;
tmp1 = NULL;
tmp2 = NULL;
obj->capacity *= 2;
}
}
if (obj->top == 0 || obj->min[obj->top - 1] >= x)//如果x小于或等于辅助栈的栈顶元素,就将x入辅助栈
{
obj->min[obj->top] = x;
}
else//否则,将原来辅助栈栈顶的元素再复制一遍放入栈顶
{
obj->min[obj->top] = obj->min[obj->top - 1];
}
obj->a[obj->top] = x;//将x放入原栈顶
obj->top++;
}
void minStackPop(MinStack* obj) {
if (obj->top == 0)//判断栈是否为空
return;
obj->top--;
}
int minStackTop(MinStack* obj) {
if (obj->top == 0)//判断栈是否为空
return;
return obj->a[obj->top - 1];
}
int minStackMin(MinStack* obj) {
if (obj->top == 0)
return;
return obj->min[obj->top - 1];
}
void minStackFree(MinStack* obj) {
free(obj->a);
free(obj->min);
obj->capacity = obj->top = 0;
free(obj);
}