《剑指offer》第五十九题II:队列的最大值

// 面试题59(二):队列的最大值
// 题目:请定义一个队列并实现函数max得到队列里的最大值,
// 要求函数max、push_back和pop_front的时间复杂度都是O(1)

#include <cstdio>
#include <deque>
#include <exception>

using namespace std;

template<typename T> class QueueWithMax
{
public:
    QueueWithMax() : currentIndex(0)
    {
    }

    void push_back(T number)
    {
        //保证最大值队列中由大到小排列
        while (!maximums.empty() && number >= maximums.back().number)  //从末尾开始比较大小
            maximums.pop_back();
        
        //将当前值载入两个队列
        InternalData internalData = { number, currentIndex };
        data.push_back(internalData);
        maximums.push_back(internalData);

        ++currentIndex;
    }

    void pop_front()
    {
        if (maximums.empty())
            throw new exception("queue is empty");

        if (maximums.front().index == data.front().index)  //弹出值是否在最大值队列中
            maximums.pop_front();
        
        data.pop_front();
    }

    T max() const
    {
        if (maximums.empty())
            throw new exception("queue is empty");

        return maximums.front().number;
    }

private:
    struct InternalData  //序列, O(1)时间没法读出索引对应值, 所以索引和对应值都保存
    {
        T number;
        int index;
    };

    deque<InternalData> data;  //保存数据的队列
    deque<InternalData> maximums;  //保存最大值的队列
    int currentIndex;  //当前索引
};
// ====================测试代码====================
void Test(const char* testName, const QueueWithMax<int>& queue, int expected)
{
    if (testName != nullptr)
        printf("%s begins: ", testName);

    if (queue.max() == expected)
        printf("Passed.\n");
    else
        printf("FAILED.\n");
}

int main(int argc, char* argv[])
{
    QueueWithMax<int> queue;
    // {2}
    queue.push_back(2);
    Test("Test1", queue, 2);

    // {2, 3}
    queue.push_back(3);
    Test("Test2", queue, 3);

    // {2, 3, 4}
    queue.push_back(4);
    Test("Test3", queue, 4);

    // {2, 3, 4, 2}
    queue.push_back(2);
    Test("Test4", queue, 4);

    // {3, 4, 2}
    queue.pop_front();
    Test("Test5", queue, 4);

    // {4, 2}
    queue.pop_front();
    Test("Test6", queue, 4);

    // {2}
    queue.pop_front();
    Test("Test7", queue, 2);

    // {2, 6}
    queue.push_back(6);
    Test("Test8", queue, 6);

    // {2, 6, 2}
    queue.push_back(2);
    Test("Test9", queue, 6);

    // {2, 6, 2, 5}
    queue.push_back(5);
    Test("Test9", queue, 6);

    // {6, 2, 5}
    queue.pop_front();
    Test("Test10", queue, 6);

    // {2, 5}
    queue.pop_front();
    Test("Test11", queue, 5);

    // {5}
    queue.pop_front();
    Test("Test12", queue, 5);

    // {5, 1}
    queue.push_back(1);
    Test("Test13", queue, 5);

    return 0;
}
测试代码

分析:分析清楚问题再写代码。搞错了front和back。

posted @ 2020-04-08 23:50  源周率  阅读(145)  评论(0编辑  收藏  举报