zoukankan      html  css  js  c++  java
  • [Algo][July][Homework]设计一个队列支持求最大值,要求O(1)

    栈和队列的基本概念:

    存放数据的线性表。

    操作:入栈/入队,出栈/出队,判断满/空

    空间复杂度:O(n)

    单次操作时间复杂度:O(1)

    栈:先进后出 FILO;队:先进先出 FIFO

    reference website:

    http://blog.csdn.net/caryaliu/article/details/8097209

    解题思路:

     1)设计一个在O(1)时间内取最大值的堆栈

    ---------update at 2018-3-20 ------------

    时隔半年,再看这道题目,觉得首先要清楚一个类可以称之为堆栈,需要具备那些功能。

    1.1)最简单,堆栈可以用一个数组来存储。

    1.2)需要实现push(压栈)方法,还有pop(出栈)方法。

    1.3)堆栈的特性是先进后出。

    ---------update end --------------------

     2)如何使用堆栈来实现一个队列

    ---------update at 2018-3-20 ------------

    2.1)队列也可以是一个数组

    2.2)队列是先进先出的

    2.3)可以用两个堆,构造一个队列。元素从A依次压栈。出栈时,如果B为空,就把A中元素依次出栈,这样最先进入A的元素在B的顶部,再从B出栈。实现先进先出

    ---------update end --------------------

    关于问题1:

    用一个变量记录当前最大数的位置maxStackItemIndex。用一个数组来记录上一个最大数的位置link2NextMaxItem[]。

    每一个数压栈,跟当前最大值比较,如果这个数比之前那个数大,那么就把上一个最大值的index保存到link2NextMaxItem[currentIndex]中,这个数的在栈的位置currentIndex记录在maxStackItemIndex中。

    push x;

    stackItem[stackTop] = x   //栈顶

    if x> stackItem[maxStackItemIndex]

      link2NextMaxItem[stackTop] = maxStackItemIndex; //因为新压栈的元素比之前的最大值要大,L2NM这个数组保存上一个最大值的index

      maxStackItemIndex = stackTop; //更新最大值的index

    else

      link2NextMaxItem[stackTop] = -1; //表示这个x不是之前压栈元素的最大值

    pop x;

    if stackTop == maxStackItemIndex    //说明弹出的是最大值

      maxStackItemIndex = link2NextMaxItem[stackTop] //最大值弹出,那么最大值的index更新为数组里保存的上一个最大值的index

    栈的O(1)求最大值:

    #include <iostream>
    using namespace std;
    #define MAXN 100
    class Stack{
    public:
        Stack(){ //构造函数
            stackTop = -1;
            maxStackItemIndex = -1;
        }
        bool isEmpty(){
            return stackTop == -1; 
        }
        bool isFull(){
            return stackTop == MAXN -1;
        }
         //元素压栈
        void push (int x){
            if(isFull()){
                cout<<"this stack is full!"<<endl;
            }
            else{
                stackItem[++stackTop] = x;
                if(x>maxValue()){
                    link2NextMaxIndex[stackTop] = maxStackItemIndex;  //把上一个最大值index记录到数组中
                    maxStackItemIndex = stackTop; //更新最大值index
                }
                else{
                    link2NextMaxIndex[stackTop] = -1; //这个index不是最大值
                }         
            }    
        }
        int maxValue(){
            if(maxStackItemIndex >= 0){
                return stackItem[maxStackItemIndex]; //返回当前最大值
            }
            else{
                return INT_MIN;
            }
        } 
        int pop(){
            int ret;
            if(isEmpty()){
                cout<<"this stack is empty"<<endl;
            }
            else{ 
                ret = stackItem[stackTop];
                    if(stackTop == maxStackItemIndex){  //弹出的是最大值
                        maxStackItemIndex = link2NextMaxIndex[stackTop]; //更新最大值index为上一个最大值的index
                }
            }
            stackTop--;
            return ret;
        }
    private:
        int link2NextMaxIndex[MAXN];
        int stackItem[MAXN];
        int stackTop;
        int maxStackItemIndex;       
    };

     关于问题2:

    创建两个栈。栈A和栈B。

    入队操作:往栈A压栈。

    出队操作:如果栈B为空,则把栈A元素依次出栈,压到栈B。栈A元素全部出栈位置。最后,栈B元素从栈顶pop。

                      如果栈B不为空,则从栈B栈顶pop。

    O(1)的求最大值:max(stackA, stackB)

    用两个栈实现队列,并且求队列最大值:

    class Queue{
    public:
        int maxValue(int x, int y){
            return x>y?x:y;
        }
        int max(){
            return maxValue(stackA.maxValue(),stackB.maxValue());
        }
        void enQueue(int x){
            if(stackA.isFull()){
                cout<<"the queue is full!"<<endl;
            }
            else{
                stackA.push(x);
            }
        }
        int deQueue(){
            if(stackB.isEmpty())
            {
                while(!stackA.isEmpty()){
                    stackB.push(stackA.pop());
                }
            }
            return stackB.pop();
        }
    private:
        Stack stackA;
        Stack stackB;
    };

    小结:

    python写多了,写C++老是记不得加“;”[捂脸]。并且老是莫名其妙想加“:”

    还有class大括号的右括号后要加";"

  • 相关阅读:
    vector的几种初始化和遍历
    剑指offer39 平衡二叉树
    和为s的两个数字
    c++参数传递的三种方式
    剑指offer40
    剑指offer28 字符串的排列
    PASCAL VOC数据集分析
    fast rcnn的实例
    cocos2dx下的A星算法
    vncserverpassword改动
  • 原文地址:https://www.cnblogs.com/hopping/p/7686641.html
Copyright © 2011-2022 走看看