关于栈常见的面试题

* 实现一个栈,要求实现push(入栈)、Pop(出栈)、Min(返回最小值)的时间复杂度为O(1)*

法1:分析:将元素与最小值封装成一个结构体

头文件:

StackAndQueueInterview.h:

// 将元素与最小值封装成一个结构体
typedef struct Elem
{
    ElemType _data;
    ElemType _minData;
}Elem;

typedef struct MinStack
{
    Stack _s;//将栈封装成最小栈
}MinStack;

void MinStackInit(MinStack* s);//初始化最小栈
void MinStackPush(MinStack* s, DataType data);//入栈
void MinStackPop(MinStack* s);//出栈
ElemType MinStackTop(MinStack* s);//获取栈顶元素
ElemType MinStackMinDate(MinStack* s);//获取最小值
int MinStackSize(MinStack* s);//获取最小栈中元素的个数
int MinStackEmpty(MinStack* s);//判空
void TestMinStack();

源文件:

初始化最小栈

void MinStackInit(MinStack* s)
{
    StackInit(&s->_s);
}

入栈

void MinStackPush(MinStack* s, ElemType data)
{
    // 封装要插入的元素
    Elem elem;
    elem._data = data;
    elem._minData = data;

    assert(s);
    // if栈为空,直接将封装好的元素入栈
    if (StackEmpty(&s->_s))
        StackPush(&s->_s, elem);

    else
    {
        Elem top = StackTop(&s->_s);
        if (top._minData < elem._data)
            elem._minData = top._minData; //更新要插入元素的最小值

        StackPush(&s->_s, elem);
    }
}

出栈

void MinStackPop(MinStack* s)
{
    assert(s);
    if (StackEmpty(&s->_s))
        return;
    StackPop(&s->_s);
}

获取栈顶元素

ElemType MinStackTop(MinStack* s)
{
    assert(MinStackEmpty(&s->_s));

    return StackTop(&s->_s)._data;
}

获取最小值

ElemType MinStackMinDate(MinStack* s)
{
    assert(MinStackEmpty(&s->_s));

    return StackTop(&s->_s)._minData;
}

获取最小栈中元素的个数

int MinStackSize(MinStack* s)
{
    return StackSize(&s->_s);
}

判空

int MinStackEmpty(MinStack* s)
{
    return StackEmpty(&s->_s);
}

测试

void TestMinStack()
{
    MinStack ms;
    MinStackInit(&ms);

    MinStackPush(&ms, 2);
    MinStackPush(&ms, 3);
    MinStackPush(&ms, 4);
    MinStackPush(&ms, 1);
    MinStackPush(&ms, 5);

    printf("size=%d\n", MinStackSize(&ms));
    printf("top=%d\n", MinStackTop(&ms));
    printf("mindata=%d\n", MinStackMinData(&ms));

    MinStackPop(&ms);
    printf("size=%d\n", MinStackSize(&ms));
    printf("top=%d\n", MinStackTop(&ms));
    printf("mindata=%d\n", MinStackMinData(&ms));

}

法2:分析:给两个栈,一个放元素,另一个放最小值

头文件:

StackAndQueueInterview.h:

// 将两个栈封装成一个栈
typedef struct MinStack
{
    Stack _data;
    Stack _minData;
}MinStack;

void MinStackInit(MinStack* s);//初始化
void MinStackPush(MinStack* s, ElemType data);//入栈
void MinStackPop(MinStack* s);//出栈
int MinStackEmpty(MinStack* s);//判空
ElemType MinStackTop(MinStack* s);//获取栈顶元素
ElemType MinStackMinData(MinStack* s);//获取最小值
int MinStackSize(MinStack* s);//获取栈中元素的个数
void TestMinStack2();//测试

源文件:

初始化

void MinStackInit(MinStack* s)
{
    StackInit(&s->_data);
    StackInit(&s->_minData);
}

入栈

void MinStackPush(MinStack* s, ElemType data)
{
    StackPush(&s->_data, data);

    //栈为空,此时data为最小值,所以将data直接放到保存最小值得栈中
    //或者,保存最小值的栈中栈顶元素的值大于data
    if (StackEmpty(&s->_minData) && data < StackTop(&s->_minData))
        StackPush(&s->_minData, data);
}

出栈

void MinStackPop(MinStack* s)
{
    if (MinStackEmpty(s))
        return;

    //当保存最小值的栈的栈顶元素与保存数据的栈的栈顶元素相等时,最小值元素才出栈
    if (StackTop(&s->_minData) == StackTop(&s->_data))
        StackPop(&s->_minData);

    StackPop(&s->_data);
}

判空

int MinStackEmpty(MinStack* s)
{
    return StackEmpty(&s->_data);
}

获取栈顶元素

ElemType MinStackTop(MinStack* s)
{
    return StackTop(&s->_data);//直接取数据栈的栈顶元素
}

获取最小值

ElemType MinStackMinData(MinStack* s)
{
    return StackTop(&s->_minData);//直接取最小值栈的栈顶元素
}

获取栈中元素的个数

int MinStackSize(MinStack* s)
{
    return StackSize(&s->_data);
}

测试

void TestMinStack2()
{
    MinStack ms;
    MinStackInit(&ms);

    MinStackPush(&ms, 2);
    MinStackPush(&ms, 3);
    MinStackPush(&ms, 4);
    MinStackPush(&ms, 1);
    MinStackPush(&ms, 5);

    printf("size=%d\n", MinStackSize(&ms));
    printf("top=%d\n", MinStackTop(&ms));
    printf("mindata=%d\n", MinStackMinData(&ms));

    MinStackPop(&ms);
    printf("size=%d\n", MinStackSize(&ms));
    printf("top=%d\n", MinStackTop(&ms));
    printf("mindata=%d\n", MinStackMinData(&ms));

}

猜你喜欢

转载自blog.csdn.net/bit666888/article/details/81165540