• leetcode622. 设计循环队列


    设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

    循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

    你的实现应该支持如下操作:

    MyCircularQueue(k): 构造器,设置队列长度为 k 。
    Front: 从队首获取元素。如果队列为空,返回 -1 。
    Rear: 获取队尾元素。如果队列为空,返回 -1 。
    enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
    deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
    isEmpty(): 检查循环队列是否为空。
    isFull(): 检查循环队列是否已满

    一)循环队列
    设计一个循环对列,重点在于在各项操作中维持数据不变式,即维持对象属性之间的正确关系。
    (1)构造函数中定义四个属性:
    self._len:队列长度
    self._elems:用于记录循环队列元素的列表
    self._head:队列中第一个元素的下标
    self._num:队列中的元素个数
    (2)进队列
    在队列尾部加入元素,并是self._num加1,以维持对象属性之间的正确关系。
    (3)出队列
    只是对列中第一个元素下标的指针后移1,同时将self._num减1。
    其余操作容易理解,可参看以下代码。
    (4)获取队列首元素
    若队列为空,即self._num等于0,返回-1;否则,返回索引self._head中的元素
    (5)获取队列尾端元素
    若对列为空,返回-1;否则,返回索引(self._head + self._num - 1) % self._len中元素,之所以要进行取模操作,是因为该队列为循环对列,存储队列元素的列表最后一个位置的下一个位置为其首位置
    (6)队列为空
    self._num为0
    (7)队列为满
    self._num等于self._len

    class MyCircularQueue {
    public:
        /** Initialize your data structure here. Set the size of the queue to be k. */
        vector<int> q;
        int p_start,num,fullNum;
        MyCircularQueue(int k) {
            p_start=0;
            num=0;
            fullNum=k;
            for(int i=0;i<k;i++)
                q.push_back(0);
        }
        
        /** Insert an element into the circular queue. Return true if the operation is successful. */
        bool enQueue(int value) {
            if(!isFull())
            {
               q[(num+p_start)%fullNum]=value;
                num++;
                return true;
            }
            return false;
        }
        
        /** Delete an element from the circular queue. Return true if the operation is successful. */
        bool deQueue() {
            if(isEmpty())
                return false;
            else
            {
                p_start=(p_start+1)%fullNum;
                num--;
                return true;
            }
        }
        
        /** Get the front item from the queue. */
        int Front() {
            if(isEmpty())
                return -1;
            else
                return q[p_start];
        }
        
        /** Get the last item from the queue. */
        int Rear() {
            if(isEmpty())
                return -1;
            else
            {
                return q[(num-1+p_start)%fullNum];
            }
        }
        
        /** Checks whether the circular queue is empty or not. */
        bool isEmpty() {
            return num==0;
        }
        
        /** Checks whether the circular queue is full or not. */
        bool isFull() {
            return num==fullNum;
        }
    };

     以下官方解法,感觉不好理解………………

    class MyCircularQueue {
    private:
        vector<int> data;
        int head;
        int tail;
        int size;
    public:
        /** Initialize your data structure here. Set the size of the queue to be k. */
        MyCircularQueue(int k) {
            data.resize(k);
            head = -1;
            tail = -1;
            size = k;
        }
        
        /** Insert an element into the circular queue. Return true if the operation is successful. */
        bool enQueue(int value) {
            if (isFull()) {
                return false;
            }
            if (isEmpty()) {
                head = 0;
            }
            tail = (tail + 1) % size;
            data[tail] = value;
            return true;
        }
        
        /** Delete an element from the circular queue. Return true if the operation is successful. */
        bool deQueue() {
            if (isEmpty()) {
                return false;
            }
            if (head == tail) {
                head = -1;
                tail = -1;
                return true;
            }
            head = (head + 1) % size;
            return true;
        }
        
        /** Get the front item from the queue. */
        int Front() {
            if (isEmpty()) {
                return -1;
            }
            return data[head];
        }
        
        /** Get the last item from the queue. */
        int Rear() {
            if (isEmpty()) {
                return -1;
            }
            return data[tail];
        }
        
        /** Checks whether the circular queue is empty or not. */
        bool isEmpty() {
            return head == -1;
        }
        
        /** Checks whether the circular queue is full or not. */
        bool isFull() {
            return ((tail + 1) % size) == head;
        }
    };
    
    /**
     * Your MyCircularQueue object will be instantiated and called as such:
     * MyCircularQueue obj = new MyCircularQueue(k);
     * bool param_1 = obj.enQueue(value);
     * bool param_2 = obj.deQueue();
     * int param_3 = obj.Front();
     * int param_4 = obj.Rear();
     * bool param_5 = obj.isEmpty();
     * bool param_6 = obj.isFull();
     */
  • 相关阅读:
    Wannafly挑战赛14 F.细胞
    D 勤奋的杨老师(二)(最小割)
    三分算法求最值
    初识最大流
    初识数据结构
    决策型DP
    哈希表
    【BZOJ】1878: [SDOI2009]HH的项链 (主席树)
    【HDU】1520 Anniversary party(树形dp)
    【UVa】1606 Amphiphilic Carbon Molecules(计算几何)
  • 原文地址:https://www.cnblogs.com/renzmin/p/11889582.html
Copyright © 2020-2023  润新知