题目描述:
设计一个栈结构,满足一下条件:min,push,pop 操作的时间复杂度为O(1)。
解题思想:
根据栈的特性,push和pop操作的时间复杂度已是O(1),难点在于怎样在常数时间内O(1)找出栈中的最小元素值。如果我们在入栈的时候同时记录栈中的最小的元素,那么我们就能够在O(1)的时间内找出min,但题目同时要求push的时间复杂度也为O(1), 那么,问题转化为怎么在O(1)的时间内让栈顶的元素同时保存栈中的最小的元素。
考虑这种情况,当每个入栈的元素都保留了在该元素之前入栈的元素的最小值,那么,在当前的元素入栈时,只需要比较前一个元素保留的最小值与当前值哪个最小,然后在当前元素中同时存储插入该元素后整个栈中的最小值,在min查找时,只需要获取栈顶元素保存的最小值遍可获得整个栈的最小元素值,而pop操作弹出一个元素时,下一个栈顶元素同样保留了整个栈的当前最小元素值。通过这种设计,min, push,pop操作的时间复杂度均达到O(1)。
源码如下:
class MinStackElement {
private:
friend class MinStack;
int data;
int minData;
MinStackElement(): data(0), minData(0) {}
~MinStackElement() {}
};
class MinStack {
private:
size_t maxSize;
size_t top;
size_t reserve;
MinStackElement *stack;
MinStack& resize(const size_t&);
public:
MinStack(size_t initSize = 10):maxSize(initSize), top(0), reserve(10), stack(new MinStackElement[maxSize]) {}
~MinStack() { delete []stack; }
MinStack& push(const int&);
int pop();
int min();
void setReserve(const size_t&);
size_t getReserve() const { return reserve; }
size_t getSize() const { return maxSize; }
};
MinStack& MinStack:: resize(const size_t& size)
{
top = top < size ? top : size;
MinStackElement *pmse = new MinStackElement[size];
for(size_t i = 0; i != top; ++i) {
pmse[i] = stack[i];
}
delete []stack;
stack = pmse;
maxSize = size;
return *this;
}
MinStack& MinStack:: push(const int& value)
{
int min;
if(top == maxSize) {
resize(maxSize + reserve);
}
stack[top].data = value;
min = stack[top].data;
if((0 != top) && (min > stack[top -1].minData)) {
min = stack[top -1].minData;
}
stack[top].minData = min;
top++;
return *this;
}
int MinStack::pop()
{
return stack[--top].data;
}
int MinStack::min()
{
return stack[top - 1].minData;
}
void MinStack::setReserve(const size_t& r)
{
reserve = r;
}