目录
队列的应用
面试题 41 : 滑动窗口的平均值
面试题 42 : 最近请求次数
队列是一种经常被使用的数据结构。如果解决某个问题时数据的插入和删除操作满足 "先进先出" 的特点,那么可以考虑用队列来存储这些数据。
例如,数组中某一长度的子数组可以看成数组的一个窗口。若给定数组 [1, 2, 3, 4, 5, 6, 7],那么子数组 [2, 3, 4] 就是其中一个大小为 3 的窗口。如果该窗口向右滑动一个数字,那么窗口就包含数字 [3, 4, 5]。如果继线向右滑动窗口,那么每向右滑动一个数字,都在窗口的最右边插入一个数字,同时把最左边的数字删除。由于最先添加进入滑动窗口的数字最先被删除,也就是 "先进先出",因此数组的这种滑动窗口可以用队列表示。
题目:
请实现如下类型 MovingAverage,计算滑动窗口中所有数字的平均值,该类型构造函数的参数确定滑动窗口的大小,每次调用成员函数 next 时都会在滑动窗口中添加一个整数,并返回滑动窗口中所有数字的平均值。
class MovingAverage {
public:
MovingAverage(int size);
double next(int val);
}
示例:
输入:
inputs = ["MovingAverage", "next", "next", "next", "next"]
inputs = [[3], [1], [10], [3], [5]]
输出:
[null, 1.0, 5.5, 4.66667, 6.0]
解释:
MovingAverage movingAverage = new MovingAverage(3);
movingAverage.next(1); // 返回 1.0 = 1 / 1
movingAverage.next(10); // 返回 5.5 = (1 + 10) / 2
movingAverage.next(3); // 返回 4.66667 = (1 + 10 + 3) / 3
movingAverage.next(5); // 返回 6.0 = (10 + 3 + 5) / 3
代码实现:
class MovingAverage {
public:
MovingAverage(int size) : capacity(size), sum(0) {}
double next(int val) {
if (q.size() == capacity)
{
sum -= q.front();
q.pop();
}
q.push(val);
sum += val;
return (double)sum / q.size();
}
private:
queue q;
int capacity;
int sum;
};
题目:
请实现如下类型 RecentCounter,它是统计过去 3000ms 内的请求次数的计数器。该类型的构造函数 RecentCounter 初始化计数器,请求数初始化为 0;函数 ping(int t) 在时间 t 添加一个新请求(t 表示以毫秒为单位的时间),并返回过去 3000ms 内(时间参数范围为 [t - 3000, t])发生的所有请求数。假设每次调用函数 ping 的参数 t 都比之前调用的参数大。
class RecentAverage {
public:
RecentAverage();
int ping(int t);
}
示例:
输入:
inputs = ["RecentCounter", "ping", "ping", "ping", "ping"]
inputs = [[], [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 {
public:
int ping(int t) {
q.push(t);
while (q.front() < t - 3000)
{
q.pop();
}
return q.size();
}
private:
queue q;
};