【编程之美】3.7 队列取最大值操作问题 ☆

之前写过栈的,以为队列的也一样,结果一点都不一样。写了好久啊。

因为栈是后进先出,先进去的数字不会影响后面的数字;而队列是先进先出,后进去的会受先进入的数字的影响。

比如: (先)  1 9 3 8 4 (后)  这样的序列

栈存储        1 9               就可以了,因为9弹出后,自然 1 就是最大的

队列则不行,如果按上面存储9弹出后 剩下 3 8 4,8是最大的,没有存储。

我的方法,保存一个max的队列

入队列时: 如果新值比 max的最前面的元素大,那么把max清空,压入新值。  因为这个元素比所有值大,并且比所有值都晚弹出。

如果不满足上面条件,但是新值比数据队列的最后一个元素大或等于,把新值压入max队列。因为队列只剩下新值上一个元素和新值时,该新值就是最大的数字。

出队列时:如果弹出的数字和max队列最前面的数字一样大,弹出max中的元素

获得最大元素:获得max的最前面的元素。

#include <iostream>
#include <queue>
using namespace std;

class My_Queue
{
public:
    My_Queue(){};
    void EnQueue(int v)
    {
        if(max.empty())
        {
            max.push(v);
        }
        else
        {
            if(v > max.front())
            {
                while(!max.empty())
                {
                    max.pop();
                }
                max.push(v);
            }
            else if(v >= data.back())
            {
                max.push(v);
            }
        }
        data.push(v);
    }

    int DeQueue()
    {
        if(data.empty())
        {
            printf("error");
            return 0;
        }

        if(!max.empty() && data.front() == max.front())
        {
            max.pop();
        }
        int del = data.front();
        data.pop();
        return del;
    }

    int MaxElement()
    {
        if(max.empty())
        {
            printf("no data\n");
            return 0;
        }
        return max.front();
    }

    queue<int> data;
    queue<int> max;
};

int main()
{
    My_Queue q;
    q.EnQueue(1);
    q.EnQueue(5);
    q.EnQueue(9);
    q.EnQueue(3);
    q.EnQueue(8);
    q.EnQueue(4);
    q.EnQueue(8);
    q.EnQueue(11);

    for(int i = 0; i < 8; i++)
    {
        printf("max:%d ", q.MaxElement());
        printf("del:%d\n", q.DeQueue());
    }

    return 0;
}

书上答案:

用两个栈A, B来构造队列,因为栈取最大可以O(1),利用栈使得队列取最大也是O(1)

数据入队列时:都压入栈B

数据出队列时: 若A为空,则把B的数据依次弹出给A,再弹出A的最后一个元素  (两次后进先出就变成了先进先出)

若A不空,直接弹出A的最后一个元素

取最大值: 取栈A 和 栈B 最大值里 更大的那一个

时间: 2024-12-21 02:18:27

【编程之美】3.7 队列取最大值操作问题 ☆的相关文章

编程之美之队列中取最大值操作

问题: 假设有这样一个拥有3个操作的队列: 1. EnQueue(v): 将v加入队列中 2. DeQueue(): 使队列中的队首元素删除并返回此元素 3. MaxElement: 返回队列中的最大元素 设计一种数据结构和算法,让MaxElement操作的时间复杂度尽可能地低. #include<iostream> #include<limits.h> using namespace std; class Stack { public: Stack() { stackTop =

队列中取最大值操作

假设有这样一个拥有3个操作的队列: 1.EnQueue(v):将v加入队列 2.DeQueue:使队列中的队首元素删除并返回元素 3.MaxElement:返回队列中的最大元素 请设计一种数据结构和算法,让MaxElement操作的时间复杂度尽可能低 研究这个问题之前,先研究两个子问题: 1.设计一个包含min操作的栈 2.用栈实现队列 一.设计一个包含min操作的栈 考虑给栈增加一个成员变量MinValue,有元素入栈的时候,将入栈元素与MinValue相比,如果小于MinValue,用入栈元

&lt;&lt;编程之美&gt;&gt; -- 队列中取最大值操作的问题

不得不说编程之美是一本好书,虽然很多题目在做acm中的过程中遇到过,不过还是有很多值得思考的地方 这是今天在编程之美上看到的一个问题,对于栈转化成队列的一个思考 平时都太过依赖c++内函数库中的栈和队列,但是对于他们的扩展我们还是应该自己进行手写栈和队列来实现更简单的算法 题目大意: 假设有这样一个拥有3个操作的队列: 1. EnQueue(v) : 将 v 加入队列 2. DeQueue: 使队列中队首元素删除并返回此元素 3.MaxElement: 返回队列中的最大元素 设计一种数据结构和算

编程之美3.7 队列中最大值问题

      这道题目的意思是,有一个队列,它里面会存储一些数值,现在,要求你需要在 O(1) 的时间内返回这个队列中最大的那个值.       这道题目的和栈中最大值最小值问题是一样的解法,都是需要一个辅助的东西,对于这道题目,我需要的是一个辅助队列.       由于是需要找到最大值,我的做法是,如果辅助队列为空,那么,当数据入队列的时候就需要同时放入队列和辅助队列中:如果辅助队列不为空,但是入队列的那个元素比辅助队列的队首元素大或者相等,那么,也是需要同时放入两个队列中:其他情况,只需要放入

编程之美——队列中取最大值操作

为实现O(1)的时间复杂度完成取队列中最大元素,使用maxStackItemIndex记录队列(使用两个栈实现)中最大元素下标,使用数组link2NextMaxItem[]记录数组中次大值的下标,这也就是使用两个栈(先进后出)模拟队列二不是直接使用队列(先进先出)的原因:先进后出可以保证当执行pop操作(pop出最大值)时可以更新maxStackItemIndex=link2NextMaxItem[stackTop]:而队列则不具有这种回溯特性: 代码: 1 #include<iostream>

编程之美---队列中取最大值操作问题

如何快速获取队列中的最大值? 最简单的办法,用一个for循环遍历,复杂度为o(n). 解法二:用大顶堆来实现,复杂度为哦o(1),但是入队和出队复杂度变为o(logN),堆中的每一个元素还得有个指针指向它的后继元素. 解法三:可以使用两个栈来模拟队列,从右边的栈进入元素相当于入队,出队时,只有当左边的栈为空时,才把右边栈的元素全部出栈到左边的栈. 1 class stack 2 { 3 public: 4 stack() 5 { 6 stackTop = -1; 7 maxItemIndex =

程之美第3章结构之法-字符串及链表的探索3.7 队列中取最大值操作问题

#include<iostream> #include<vector> using namespace std; class stack { private: vector<int> vec;//用来保存当前进栈的值 vector<int> max_vec; public: void push(int a) { vec.push_back(a); if(max_vec.size()==0||a>vec[max_vec[max_vec.size()-1]

队列中取最大值操作问题

问题: 假设有这样一个拥有3个操作的队列: 1. EnQueue(v): 将v加入队列中 2. DeQueue(): 使队列中的队首元素删除并返回此元素 3. MaxElement: 返回队列中的最大元素 设计一种数据结构和算法,让MaxElement操作的时间复杂度尽可能地低. 思路: (1)用两个栈设计一个新的数据类型(数据类型定义为MyStack),其中一个栈用来存放数据,另一个栈用来存放最大值, 当插入数据时,第一个栈接受数据进行入栈操作,第二栈首先判断一下栈顶元素和插入元素的大小,如果

3.7 队列中取最大值操作问题

问题: 假设有这样一个拥有3个操作的队列: 1. EnQueue(v): 将v加入队列中 2. DeQueue(): 使队列中的队首元素删除并返回此元素 3. MaxElement: 返回队列中的最大元素 设计一种数据结构和算法,让MaxElement操作的时间复杂度尽可能地低. 方法:用两个栈来模拟队列 在代码中,maxStackItemIndex代表栈中最大的数的下标 link2NextMaxItem[index]表示当前index这个下标代表的数字(当前是最大的)如果没有的话,那么最大的那