《剑指 Offer》专项突破版 - 面试题 41 和 42 : 详解队列的应用(C++ 实现)

目录

队列的应用

面试题 41 : 滑动窗口的平均值

面试题 42 : 最近请求次数


 


队列的应用

队列是一种经常被使用的数据结构。如果解决某个问题时数据的插入和删除操作满足 "先进先出" 的特点,那么可以考虑用队列来存储这些数据

例如,数组中某一长度的子数组可以看成数组的一个窗口。若给定数组 [1, 2, 3, 4, 5, 6, 7],那么子数组 [2, 3, 4] 就是其中一个大小为 3 的窗口。如果该窗口向右滑动一个数字,那么窗口就包含数字 [3, 4, 5]。如果继线向右滑动窗口,那么每向右滑动一个数字,都在窗口的最右边插入一个数字,同时把最左边的数字删除。由于最先添加进入滑动窗口的数字最先被删除,也就是 "先进先出",因此数组的这种滑动窗口可以用队列表示

 


面试题 41 : 滑动窗口的平均值

题目

请实现如下类型 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<int> q;
    int capacity;
    int sum;
};


面试题 42 : 最近请求次数

题目

请实现如下类型 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<int> q;
};

最近更新

  1. TCP协议是安全的吗?

    2024-02-15 18:22:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-15 18:22:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-15 18:22:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-15 18:22:02       20 阅读

热门阅读

  1. P1008 [NOIP1998 普及组] 三连击

    2024-02-15 18:22:02       31 阅读
  2. 蔚来面试解答

    2024-02-15 18:22:02       29 阅读
  3. 【在 Ubuntu 上配置 Nginx 作为 Web 服务器】

    2024-02-15 18:22:02       35 阅读
  4. Momentum2

    Momentum2

    2024-02-15 18:22:02      21 阅读
  5. C++重新入门-基本输入输出

    2024-02-15 18:22:02       31 阅读
  6. 【开源讲解】

    2024-02-15 18:22:02       32 阅读
  7. win+X无反应,开始菜单右击无反应

    2024-02-15 18:22:02       34 阅读
  8. 解决谷歌Chrome浏览器翻译:无法翻译此网页

    2024-02-15 18:22:02       24 阅读
  9. 2月12作业

    2024-02-15 18:22:02       31 阅读