面试100题:2.设计包含min函数的栈

转载并参考July的博客http://topic.csdn.net/u/20101126/10/b4f12a00-6280-492f-b785-cb6835a63dc9.html,万分感谢!

题目

定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。结合链表一起做。提示:结合链表一起做。

分析

要想求得复杂度是O(1)的算法,基本思路是设计一个辅助栈,该栈随时更新保存的当前所有数据的最小值。即一发现有更小的值,就把数据压入该辅助站中。

解一

利用C++Template可以增强代码的复用性。同时,结合vector类型内置的push_back(),pop_back()函数可以简化操作。

/*Title: 2.设计包含min函数的栈:解一
Author:  gocode
Date:    2012-09-29*/

#include <iostream>
#include <assert.h>
#include <vector>
using namespace std;

template <typename T>
class StackSuppliedMin
{
public:
    vector<T> datas; // 保存值的数据栈
    vector<T> minStack; // 辅助栈,保存最小值位置,记住这里只是记录了最小值在datas的位置

    // 进栈操作
    void Push(T data)
    {
        datas.push_back(data);
        if (minStack.empty() || data < datas[minStack.back()])
            minStack.push_back(datas.size()-1);
    }

    // 出栈操作
    void Pop()
    {
        //assert(!datas.empty());
        if (!datas.empty() && datas.back() == datas[minStack.back()])
            minStack.pop_back();
        datas.pop_back();
    }

    // 返回栈顶数据值
    T Peek()
    {
        //assert(!datas.empty());
        if (!datas.empty())
            return datas.back();
        else
        {
            cout<<"Data stack is empty.";
            return NULL;
        }
    }
    // 获得最小值
    T GetMinimal()
    {
        //assert(!datas.empty() && !minStack.empty());
        if (!datas.empty() && !minStack.empty())
            return datas[minStack.back()];
        else
        {
            cout<<"Minimal stack is empty.";
            return NULL;
        }
    }

    // 列出栈里的数据
    void displayStack(vector<T> theStack)
    {
        if (!theStack.empty())
        {
            for (vector<T>::iterator it = theStack.begin(); it != theStack.end(); ++it)
                cout<<*it<<" ";
 
            cout<<endl;
        }
        else
            cout<<"No data in the stack."<<endl;
    }
};

void main()
{
    StackSuppliedMin<int> myStackClass;

    // 推进栈,并显示变化情况
    myStackClass.Push(2);
    cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    myStackClass.Push(6);
    cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    myStackClass.Push(4);
    cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    myStackClass.Push(1);
    cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    myStackClass.Push(5);
    cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    cout<<"Current stacks status: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    // 弹出栈,并显示当前变化情况
    cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
    myStackClass.Pop();
    cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
    cout<<"After pop the 2 stacks contain: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
    myStackClass.Pop();
    cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
    cout<<"After pop the 2 stacks contain: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
    myStackClass.Pop();
    cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
    cout<<"After pop the 2 stacks contain: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
    myStackClass.Pop();
    cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
    cout<<"After pop the 2 stacks contain: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
    myStackClass.Pop();
    cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
    cout<<"After pop the 2 stacks contain: "<<endl;
    myStackClass.displayStack(myStackClass.datas);
    myStackClass.displayStack(myStackClass.minStack);
    cout<<endl;

    system("pause");
}

结果
面试100题:2.设计包含min函数的栈_第1张图片 

解二

使用传统链表构造栈,链表节点有两个值,一个是当前节点的值,另一个是栈中最小值。这样同样能够解决问题。

/*Title: 2.设计包含min函数的栈:解二
Author:  gocode
Date:    2012-09-29*/

#include <iostream>
using namespace std;

struct MinStackElement
{
    int data;
    int min;
};

struct MinStack
{
    MinStackElement *item;
    int size;
    int top;
};

MinStack MinStackInit(int maxSize)
{
    MinStack stack;
    stack.size = maxSize;
    stack.item = (MinStackElement *) malloc (sizeof(MinStackElement)*maxSize);
    stack.top = 0;
    return stack;
}

void MinStackFree(MinStack stack)
{
    free(stack.item);
    stack.size = 0; // 表示栈里数据的容量
    stack.top = 0; // 表示栈顶
}

// 把数值压入栈顶
void MinStackPush(MinStack &stack, int d)
{
    if (stack.top == stack.size)
    {
            cout<<"out of stack space."<<endl;
            return;
    }
 
    // 指向栈顶,并赋值d
    MinStackElement *p = &stack.item[stack.top];
    p->data = d;
    // 先赋值原最小值,然后和data作比较判断出当前最小值
    p->min = (stack.top==0 ? d : stack.item[stack.top-1].min);
    if (p->min > d)
        p->min = d;
    stack.top++;
}

// 弹出栈中栈顶数据
void MinStackPop(MinStack &stack)
{
    if (stack.top == 0)
    {
        cout<<"stack is empty."<<endl;
        return ;
    }
    --stack.top;
}

// 求得栈中当前最小值
int MinStackMin(MinStack &stack)
{
    if (stack.top == 0)
    {
        cout<<"stack is empty."<<endl;
        return NULL;
    }
    return stack.item[stack.top-1].min;
}

int MinStackPeek(MinStack stack)
{
    if (stack.top == 0)
    {
        cout<<"stack is empty."<<endl;
        return NULL;
    }
    return stack.item[stack.top-1].data;
}

// 显示栈中数据
void MinStackDisplay(MinStack stack)
{
    if (stack.size == 0)
    {
        cout<<"stack is empty."<<endl;
        return;
    }
    else
    {
        for (int i = 0; i < stack.top; i++)
        {
            cout<<stack.item[i].data<<" ";
        }
        cout<<endl;
    }
}

void main()
{
    MinStack thestack = MinStackInit(5);
    MinStackPush(thestack, 2);
    MinStackPush(thestack, 6);
    MinStackPush(thestack, 4);
    MinStackPush(thestack, 1);
    MinStackPush(thestack, 5);

    MinStackDisplay(thestack);

    cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
    MinStackPop(thestack);
    cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
    MinStackDisplay(thestack);

    cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
    MinStackPop(thestack);
    cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
    MinStackDisplay(thestack);

    cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
    MinStackPop(thestack);
    cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
    MinStackDisplay(thestack);

    cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
    MinStackPop(thestack);
    cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
    MinStackDisplay(thestack);

    cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
    MinStackPop(thestack);
    cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
    MinStackDisplay(thestack);
    system("pause");
}

结果
面试100题:2.设计包含min函数的栈_第2张图片

你可能感兴趣的:(面试100题:2.设计包含min函数的栈)