五月集训(第16天)—队列

队列

1. 933. 最近的请求次数

    思路:
        有新的ping请求,则入队,将t - 3000之前的请求出队。查询[t - 3000, t]的请求次数。

class RecentCounter {
    int front, rear;
    int data[10010];
public:
    RecentCounter() {
        front = 0;
        rear = -1;
    }
    
    int ping(int t) {
        data[++rear] = t;
        while ( rear - front + 1 > 0 && data[front] + 3000 < t ) {
            front++;
        }
        return rear - front + 1;
    }
};

/**
 * Your RecentCounter object will be instantiated and called as such:
 * RecentCounter* obj = new RecentCounter();
 * int param_1 = obj->ping(t);
 */

2. 2073. 买票需要的时间

    思路:
        买完票的人队首出队,若还需买票则队尾入队,一直到第k个人买完票即可。

class Solution {
public:
    int timeRequiredToBuy(vector<int>& tickets, int k) {
        int t = 0;
        int n = tickets.size();
        while (tickets[k]) {
            for (int i = 0; i < n; i++) {
                if (tickets[i] == 0) continue;
                tickets[i]--;
                t++;
                if (tickets[k] == 0) break;
            }
        }
        return t;
    }
};

3. 641. 设计循环双端队列

    思路:
        按要求模拟即可,注意双端队列的空间应该开两倍大,frontrear从中间开始读。

class MyCircularDeque {
    int Que[4010];
    int front, rear;
    int limit;
public:
    MyCircularDeque(int k) {
        front = 2005;
        rear = 2004;
        limit = k;
    }
    
    bool insertFront(int value) {
        if (isFull()) return false;

        Que[--front] = value;
        return true;
    }
    
    bool insertLast(int value) {
        if (isFull()) return false;

        Que[++rear] = value;
        return true;
    }
    
    bool deleteFront() {
        if (isEmpty()) return false;

        front++;
        return true;
    }
    
    bool deleteLast() {
        if (isEmpty()) return false;

        rear--;
        return true;
    }
    
    int getFront() {
        if (isEmpty()) return -1;
        return Que[front];
    }
    
    int getRear() {
        if (isEmpty()) return -1;
        return Que[rear];
    }
    
    bool isEmpty() {
        if (rear - front + 1 <= 0) return true;
        else return false;
    }
    
    bool isFull() {
        if (rear - front + 1 == limit) return true;
        else return false;
    }
};

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque* obj = new MyCircularDeque(k);
 * bool param_1 = obj->insertFront(value);
 * bool param_2 = obj->insertLast(value);
 * bool param_3 = obj->deleteFront();
 * bool param_4 = obj->deleteLast();
 * int param_5 = obj->getFront();
 * int param_6 = obj->getRear();
 * bool param_7 = obj->isEmpty();
 * bool param_8 = obj->isFull();
 */

4. 1670. 设计前中后队列

    思路:
        按要求模拟。注意middlepushpop的插入位置,可以手写几个找规律。

class FrontMiddleBackQueue {
    int data[2010];
    int front, rear;
public:
    FrontMiddleBackQueue() {
        front = 1005;
        rear = 1004;
    }
    
    void pushFront(int val) {
        data[--front] = val;
    }
    
    void pushMiddle(int val) {
        //  X           front - 1
        //  XX          front + 1
        //  xxx         front + 1
        //  xxxx        front + 2
        //  xxxxx       front + 3
        int num =  rear - front + 1;
        if (num == 0) data[--front] = val;
        else {
            int x = num / 2;
            for (int i = rear;  i >= front + x; i--) data[i + 1] = data[i];
            data[front + x] = val;
            rear++;
        }
    }
    
    void pushBack(int val) {
        data[++rear]  =val;
    }
    
    int popFront() {
        if (rear - front + 1 == 0) return -1;
        else return data[front++];
    }
    
    int popMiddle() {
        // x            front
        // xx           front
        // xxx          front + 1
        // xxxx         front + 1
        // xxxxx        front + 2
        int num = rear - front + 1;
        if (num == 0) return -1;
        else {
            int x = (num - 1) / 2;
            int ans = data[front + x];
            for (int i = front + x; i < rear; i++) data[i] = data[i + 1];
            rear--;
            return ans;
        }
    }
    
    int popBack() {
        if (rear - front + 1 == 0) return -1;
        else return data[rear--];
    }
};

/**
 * Your FrontMiddleBackQueue object will be instantiated and called as such:
 * FrontMiddleBackQueue* obj = new FrontMiddleBackQueue();
 * obj->pushFront(val);
 * obj->pushMiddle(val);
 * obj->pushBack(val);
 * int param_4 = obj->popFront();
 * int param_5 = obj->popMiddle();
 * int param_6 = obj->popBack();
 */
posted @ 2022-05-16 07:16  番茄元  阅读(25)  评论(0)    收藏  举报