笔试题:设计包含min 函数的栈

题目:设计包含min 函数的栈。定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素。要求函数min、push 以及pop 的时间复杂度都是O(1)。


解答:开始的时候很容易想到一个方法就是在栈结构中增加一个变量用来记录当前栈中最小元素的值minData,这样在push的时候更新这个minData值,那么在min函数和push函数时间复杂度确实为O(1),但是有一个问题,在pop的时候,如何更新这个minData的值?如果pop的时候正好是这个minData,那么剩余栈中的最小值如何知道,没办法知道。所以显然这种简单的想法是不行的,必须设计其他的结构。

原来的简单栈中,每一个数据元素只包括一个数据,为了适应这种min函数的要求,那么必须在栈结构中存储最小值minData,但是只是在整个栈中加一个minData,pop操作之后不能更新。所以可以想到在每个数据元素中加一个min变量,用于存储当前位置到栈底所有元素的最小值,这样一来,即使pop了栈顶元素,下一个元素的min存储的是剩余元素的最小值,所以可以满足min,push,pop的时间复杂度都是O(1)的要求。

如下图所示为栈的结构,比如依次push  7,5,3,-1,9,10,10到栈中,那么相应的元素的min值是7,5,3,-1,-1,-1,-1。

                                     

                              

以下为实现代码

// 栈元素结构
struct MinStackElement {
    int data; // 数据
    int min;  // 当前位置到栈底的最小值
};

// 栈结构
struct MinStack {
    MinStackElement *pData;
    int size;
    int top;
};

// 初始化栈
MinStack MinStackInit(int maxSize) {
    MinStack stack;
    stack.size = maxSize;
    stack.pData = (MinStackElement*) malloc(sizeof(MinStackElement)*maxSize);
    stack.top = 0;
    return stack;
}

// 释放栈内存
void MinStackFree(MinStack stack) {
    free(stack.pData);
}

// 压栈操作,压栈的同时设置元素的min值
void MinStackPush(MinStack *stack, int d) {
    if (stack->top == stack->size)
        cout << "栈已满" << endl;
    MinStackElement p;
    p.data = d;
    p.min = (stack->top==0?d:stack->pData[stack->top-1].data);
    if (p.min > d)
        p.min = d;
    stack->pData[stack->top] = p;
    stack->top ++;
}

// 出栈操作
int MinStackPop(MinStack *stack) {
    if (stack->top == 0)
        cout << "空栈" << endl;
    return stack->pData[--stack->top].data;
}

// 最小值函数
int MinStackMin(MinStack stack) {
    if (stack.top == 0)
        cout << "空栈" << endl;
    return stack.pData[stack.top-1].min;
}


int main()
{
    // 初始化栈
    MinStack stack = MinStackInit( 50 );

    // 将元素压入栈中
    MinStackPush(&stack, 10);
    MinStackPush(&stack, 9);
    MinStackPush(&stack, -1);
    MinStackPush(&stack, 2);
    MinStackPush(&stack, 5);
    MinStackPush(&stack, 10);

    // 出栈元素
    cout << MinStackPop(&stack) << endl;

    // 找出最小元素
    cout << MinStackMin(stack) << endl;

    system( "pause" );
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值