LeetCode 刷题 [C++] 第[641]题. 设计循环双端队列

题目描述

设计实现双端队列。
你的实现需要支持以下操作:
MyCircularDeque(k):构造函数,双端队列的大小为k。
insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true。
insertLast():将一个元素添加到双端队列尾部。如果操作成功返回 true。
deleteFront():从双端队列头部删除一个元素。 如果操作成功返回 true。
deleteLast():从双端队列尾部删除一个元素。如果操作成功返回 true。
getFront():从双端队列头部获得一个元素。如果双端队列为空,返回 -1。
getRear():获得双端队列的最后一个元素。 如果双端队列为空,返回 -1。
isEmpty():检查双端队列是否为空。
isFull():检查双端队列是否满了。
提示:
所有值的范围为 [1, 1000]
操作次数的范围为 [1, 1000]
请不要使用内置的双端队列库。

解题思路一

首先定义一个数组作为存数据的buffer,还需要定义一个容量变量capacity,然后是队首指针front和队尾指针rear。
1、初始化首指针front=0,尾指针rear=0。在队首入队列时,先移动指针,再赋值;而在队尾入队时,先赋值,再移动指针。首尾指针的意义如下:
front:指向队列头部第1个有效数据的位置;
rear:指向队列尾部(即最后 1 个有效数据)的下一个位置,即下一个从队尾入队元素的位置。
2、判断“队列为空”和“队列为满”的条件。为避免两者冲突,特意空出了一个位置,即初始化容量capacity=k+1。
空出一个位置的主要作用是:循环数组中任何时刻一定至少有一个位置不存放有效元素。
这样判别队列为空的条件是:front == rear;
判别队列为满的条件是:(rear + 1) % capacity == front;。
这样就可以理解为,当rear循环到数组的前面,要从后面追上front,还差一格的时候,判定队列为满。
3、因为有循环的出现,要特别注意处理数组下标可能越界的情况。
(1)指针后移的时候,索引+1,要取模((front/rear + 1)%capacity);
(2)指针前移的时候,为了循环到数组的末尾,需要先加上数组的长度,然后再对数组长度取模((front/rear - 1 + capacity)%capacity)。

class MyCircularDeque {
private:
    vector<int> buffer;
    int capacity;
    int front;
    int rear;

public:
    /** Initialize your data structure here. Set the size of the deque to be k. */
    MyCircularDeque(int k) {
        capacity = k+1;
        buffer.assign(capacity,0);
        front = 0;
        rear = 0;
    }
    
    /** Adds an item at the front of Deque. Return true if the operation is successful. */
    bool insertFront(int value) {
        if(isFull()) return false;
        front = (front-1+capacity)%capacity;
        buffer[front] = value;
        return true;
    }
    
    /** Adds an item at the rear of Deque. Return true if the operation is successful. */
    bool insertLast(int value) {
        if(isFull()) return false;
        buffer[rear] = value;
        rear = (rear+1)%capacity;
        return true;
    }
    
    /** Deletes an item from the front of Deque. Return true if the operation is successful. */
    bool deleteFront() {
        if(isEmpty()) return false;
        front = (front+1)%capacity;
        return true;
    }
    
    /** Deletes an item from the rear of Deque. Return true if the operation is successful. */
    bool deleteLast() {
        if(isEmpty()) return false;

        rear = (rear-1+capacity)%capacity;
        return true;
    }
    
    /** Get the front item from the deque. */
    int getFront() {
        if(isEmpty()) return -1;
        return buffer[front];
    }
    
    /** Get the last item from the deque. */
    int getRear() {
        if(isEmpty()) return -1;
        return buffer[(rear-1+capacity)%capacity];
    }
    
    /** Checks whether the circular deque is empty or not. */
    bool isEmpty() {
        return rear == front;
    }
    
    /** Checks whether the circular deque is full or not. */
    bool isFull() {
        return front == (rear + 1 )%capacity;
    }
};

解题思路二

同样定义一个数组作为存数据的buffer,还需要定义一个容量变量capacity以及一个现在队列中有效元素数量size,然后是队首指针front和队尾指针rear。
1、初始化首指针front=0,尾指针rear=0。在在队首入队列时,先移动指针,再赋值;而在队尾入队时,先赋值,再移动指针。首尾指针的意义如下:
front:指向队列头部第1个有效数据的位置;
rear:指向队列尾部(即最后 1 个有效数据)的下一个位置,即下一个从队尾入队元素的位置。
2、判断“队列为空”和“队列为满”的条件。
这样判别队列为空的条件是:size<1;
判别队列为满的条件是:size == capacity;。
3、同样要特别注意处理数组下标可能越界的情况。
(1)指针后移的时候,索引+1,要取模((front/rear + 1)%capacity);
(2)指针前移的时候,为了循环到数组的末尾,需要先加上数组的长度,然后再对数组长度取模((front/rear - 1 + capacity)%capacity)。

class MyCircularDeque {
private:
    vector<int> buffer;
    int capacity;
    int front;
    int rear;
    int size;

public:
    /** Initialize your data structure here. Set the size of the deque to be k. */
    MyCircularDeque(int k) {
        capacity = k;
        buffer.assign(capacity,0);
        front = 0;
        rear = 0;
        size = 0;
    }
    
    /** Adds an item at the front of Deque. Return true if the operation is successful. */
    bool insertFront(int value) {
        if(isFull()) return false;
        front = (front-1+capacity)%capacity;
        buffer[front] = value;
        ++size;
        return true;
    }
    
    /** Adds an item at the rear of Deque. Return true if the operation is successful. */
    bool insertLast(int value) {
        if(isFull()) return false;
        buffer[rear] = value;
        rear = (rear+1)%capacity;
        ++size;
        return true;
    }
    
    /** Deletes an item from the front of Deque. Return true if the operation is successful. */
    bool deleteFront() {
        if(isEmpty()) return false;
        front = (front+1)%capacity;
        --size;
        return true;
    }
    
    /** Deletes an item from the rear of Deque. Return true if the operation is successful. */
    bool deleteLast() {
        if(isEmpty()) return false;
        rear = (rear-1+capacity)%capacity;
        --size;
        return true;
    }
    
    /** Get the front item from the deque. */
    int getFront() {
        if(isEmpty()) return -1;
        return buffer[front];
    }
    
    /** Get the last item from the deque. */
    int getRear() {
        if(isEmpty()) return -1;
        return buffer[(rear-1+capacity)%capacity];
    }
    
    /** Checks whether the circular deque is empty or not. */
    bool isEmpty() {
        return size < 1;
    }
    
    /** Checks whether the circular deque is full or not. */
    bool isFull() {
        return size == capacity;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值