C++小白修仙记_LeetCode刷题_队列

队列 (难度:easy)

933. 最近的请求次数

  1. 最近的请求次数
    设计 队列 数据流
    写一个 RecentCounter 类来计算特定时间范围内最近的请求。

请你实现 RecentCounter 类:

RecentCounter() 初始化计数器,请求数为 0 。
int ping(int t) 在时间 t 添加一个新请求,其中 t 表示以毫秒为单位的某个时间,并返回过去 3000 毫秒内发生的所有请求数(包括新请求)。确切地说,返回在 [t-3000, t] 内发生的请求数。
保证 每次对 ping 的调用都使用比之前更大的 t 值。

示例

输入:

["RecentCounter", "ping", "ping", "ping", "ping"]

[[], [1], [100], [3001], [3002]]

输出:
[null, 1, 2, 3, 3]

解释:

RecentCounter recentCounter = new RecentCounter();
recentCounter.ping(1); // requests = [1],范围是 [-2999,1],返回 1

recentCounter.ping(100); // requests = [1, 100],范围是 [-2900,100],返回 2

recentCounter.ping(3001); // requests = [1, 100, 3001],范围是 [1,3001],返回 3

recentCounter.ping(3002); // requests = [1, 100, 3001, 3002],范围是 [2,3002],返回 3

解答:

class RecentCounter {
    queue<int> q;

public:
    RecentCounter() {}

    int ping(int t) {
        q.push(t);
        while (q.front() < t - 3000) {
            q.pop();
        }
        return q.size();
    }
};

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

1700. 无法吃午餐的学生数量

学校的自助午餐提供圆形和方形的三明治,分别用数字 0 和 1 表示。所有学生站在一个队列里,每个学生要么喜欢圆形的要么喜欢方形的。
餐厅里三明治的数量与学生的数量相同。所有三明治都放在一个 栈 里,每一轮:

如果队列最前面的学生 喜欢 栈顶的三明治,那么会 拿走它 并离开队列。
否则,这名学生会 放弃这个三明治 并回到队列的尾部。
这个过程会一直持续到队列里所有学生都不喜欢栈顶的三明治为止。

给你两个整数数组 students 和 sandwiches ,其中 sandwiches[i] 是栈里面第 i​​​​​​ 个三明治的类型(i = 0 是栈的顶部), students[j] 是初始队列里第 j​​​​​​ 名学生对三明治的喜好(j = 0 是队列的最开始位置)。请你返回无法吃午餐的学生数量。

示例

输入:students = [1,1,0,0], sandwiches = [0,1,0,1]

输出:0

解释:

  • 最前面的学生放弃最顶上的三明治,并回到队列的末尾,学生队列变为 students = [1,0,0,1]。
  • 最前面的学生放弃最顶上的三明治,并回到队列的末尾,学生队列变为 students = [0,0,1,1]。
  • 最前面的学生拿走最顶上的三明治,剩余学生队列为 students = [0,1,1],三明治栈为 sandwiches = [1,0,1]。
  • 最前面的学生放弃最顶上的三明治,并回到队列的末尾,学生队列变为 students = [1,1,0]。
  • 最前面的学生拿走最顶上的三明治,剩余学生队列为 students = [1,0],三明治栈为 sandwiches = [0,1]。
  • 最前面的学生放弃最顶上的三明治,并回到队列的末尾,学生队列变为 students = [0,1]。
  • 最前面的学生拿走最顶上的三明治,剩余学生队列为 students = [1],三明治栈为 sandwiches = [1]。
  • 最前面的学生拿走最顶上的三明治,剩余学生队列为 students = [],三明治栈为 sandwiches = []。
    所以所有学生都有三明治吃。

解法:不看队列顺序 仅计算对应0 和 1 的数量

class Solution {
public:
    int countStudents(vector<int>& students, vector<int>& sandwiches) {
        int n = students.size();
        int m = sandwiches.size();
        int count_0 = 0; // 圆形
        int count_1 = 0; // 方形
        for (int i = 0; i < n; i++) {
            if (students[i] == 0) {
                count_0++;
            } else if (students[i] == 1) {
                count_1++;
            } else {
                return 0;
            }
        }

        for (int i = 0; i < m; i++) {
            if (sandwiches[i] == 0 && count_0 > 0) {
                count_0--;
            } else if (sandwiches[i] == 1 && count_1 > 0) {
                count_1--;
            } else {
                break;
            }
        }

        return count_0 + count_1;
    }
};

解法:利用数据结构

class Solution {
public:
    int countStudents(vector<int>& students, vector<int>& sandwiches) {
        queue<int> q; // 学生队列
        // 初始化队列和栈
        for (int student : students) {
            q.push(student);
        }
        int count = 0; // 连续不匹配计数器
        int i = 0;
        while (!q.empty()) {
            int student = q.front();
            q.pop();

            if (student == sandwiches[i]) {
                // 匹配:取走三明治
                i++;
                count = 0; // 重置计数器
            } else {
                // 不匹配:重新排队
                q.push(student);
                count++;

                // 检查是否所有学生都不喜欢当前三明治
                if (count == q.size()) {
                    return q.size();
                }
            }
        }
        return 0; // 所有学生都吃到三明治
    }
};

232. 用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:

你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例

输入:

["MyQueue", "push", "push", "peek", "pop", "empty"]

[[], [1], [2], [], [], []]

输出:

[null, null, null, 1, 1, false]

解释:

MyQueue myQueue = new MyQueue();

myQueue.push(1); // queue is: [1]

myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)

myQueue.peek(); // return 1

myQueue.pop(); // return 1, queue is [2]

myQueue.empty(); // return false

class MyQueue {
    stack<int> outs, ins;

public:
    MyQueue() {}

    void push(int x) {
        ins.push(x);
    }

    int pop() {
        if(outs.empty()){
            while(!ins.empty()){
                outs.push(ins.top());
                ins.pop();
            }
        }

        int x = outs.top();
        outs.pop();
        return x;
    }

    int peek() {
        if(outs.empty()){
            while(!ins.empty()){
                outs.push(ins.top());
                ins.pop();
            }
        }
        return outs.top();
    }

    bool empty() {
        return ins.empty() && outs.empty();
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */
posted @ 2025-09-08 18:20  Jaylan  阅读(10)  评论(0)    收藏  举报