数据结构和算法经典100题-第2题

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

题目分析
这是一个传统的经典题目,设计一个栈结构,提供时间复杂度是O(1)的三个方法:min、push、pop。
push和pop两个方法时间复杂度是O(1)很容易实现。而min方法的时间复杂度是O(1),则要求我们在获取最小值时不能遍历栈内元素(若遍历栈内元素,则min的时间复杂度是O(n))。这里我想到的方法是设计一个缓存的栈,记录下最小值。在原栈pop和push操作时,同步更新缓存栈的内容。
缓存栈的基本思想如下图所示:

设计栈的基本结构
栈的基本结构图
有了以上的分析,min、pop和push方法很容易实现,实现的代码如下:

#include <stdio.h>
#include <vector>
#include <iostream>
usingnamespacestd;

template<typename T>
class stackMin {
public:
    stackMin() { m_top = -1;};/* top = -1表示栈为空 */
    ~stackMin(){};
    bool pop(T & value){
        if (-1 == m_top ) {
            returnfalse;
        }
        value = m_obj.back();
        m_obj.pop_back();
        m_cache.pop_back();
        m_top--;
        returntrue;
    }

    bool push(T & value){
        T tmp;
        if (m_cache.empty()) {
            tmp = value;
        } else {
            tmp = m_cache.back();
        }

        if (value < tmp) {
            tmp = value;
        }
        m_cache.push_back(tmp);
        m_obj.push_back(value);
        m_top++;
        returntrue;

    }

    T & min() {
        returnm_cache.back();
    }
private:
    int m_top;
    vector<T> m_obj;
    vector<T> m_cache;
};
int test_2();

#endif

下面是对以上代码的测试代码:

int test_2() {
    stackMin<int> obj;
    int popValue = 0;
    int a[] = {10,7,3,3,8,5,2,6};
    printf("Pushing,min of value: \n");
    for (int i = 0; i < 8; i++) {
        obj.push(a[i]);
        printf("push(%d),min(%d)\n",a[i],obj.min());
    }

    printf("\n Poping \n");
    for (int i = 0; i < 8; i++) {
        printf("pop(%d),min(%d)\n",popValue,obj.min());
        obj.pop(popValue);
    }
    printf("\n");

    return 0;
}
int main(void) {
    test_2();
}

测试结果的打印输出:


打印输出:
Pushing,min of value:
push(10),min(10)
push(7),min(7)
push(3),min(3)
push(3),min(3)
push(8),min(3)
push(5),min(3)
push(2),min(2)
push(6),min(2)
Poping
pop(0),min(2)
pop(6),min(2)
pop(2),min(3)
pop(5),min(3)
pop(8),min(3)
pop(3),min(3)
pop(3),min(7)
pop(7),min(10)


Okay,到这里第二道题解决完毕,路漫漫还有98道题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值