五月集训(第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. 设计循环双端队列
思路:
按要求模拟即可,注意双端队列的空间应该开两倍大,front
和rear
从中间开始读。
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. 设计前中后队列
思路:
按要求模拟。注意middle
的push
和pop
的插入位置,可以手写几个找规律。
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();
*/
东方欲晓,莫道君行早。