四、数据结构之"队列-最近请求次数"

96 阅读2分钟

1.队列是什么?

  • 一个先进先出的数据结构
  • JavaScript中没有队列,但是可以用Array实现队列的所有功能

image.png

  • 先入队两个元素 image.png

  • 出队的时候 先进入的先出 image.png

// 队列使用数组来模拟
const queue = [];

// 入队
queue.push('1')
queue.push('2')

// 出队
const q1 = queue.shift();
const q2 = queue.shift();

2.什么场景使用队列?

  1. 中午排队吃饭,先排先吃===先进先出,依次执行
  2. JavaScript异步中的任务队列
  3. 计算最近请求次数 算法题 LeetCode

3.JS 异步队列

image.png

一、JS异步的原理与进阶 点击链接查看

  • JavaScript是单线程的,无法同时处理异步中的并发任务
  • 不了解js异步的可以先学习了解一下event loop 事件循环机制
  • 使用任务队列先后处理异步任务.
  • 必须使用队列先进先出的特性,让这些并发任务依次排队执行
a. 同步代码,一行一行放在Call Satck执行 
b. 遇到异步,会先"进行记录",等待时机(定时,网络请求) 
c. 时机(时间到了),移动到callback queue(回调队列)中 
d. 如果CallSatck为空(同步代码执行完) Event Loop 开始工作 
e. 开始轮询查找Callback Queue,找到之后移动到Call Stack 执行 
f. 然后继续轮询查找,直至为空

4.计算最近请求次数 933

  • 有新请求就入队,3000ms 前发出的请求出队.
  • 队列的长度就是最近请求次数
  • 越早发出的请求越早不在最近的3000ms内的请求里
  • 满足先进先出,考虑用队列.
  • 解题步骤: 1.有新请求就入队,3000ms前发出的请求出队 2.队列的长度就是最近请求次数 题目
    1. 写一个 RecentCounter 类来计算特定时间范围内最近的请求。
    2. 请你实现 RecentCounter 类:
    3. RecentCounter() 初始化计数器,请求数为 0 。
    4. int ping(int t) 在时间 t 添加一个新请求,其中 t 表示以毫秒为单位的某个时间,并 返回过去 3000 毫秒内发生的所有请求数(包括新请求)。确切地说,返回在 [t-3000,t] 内发生的请求数。
    5. 保证 每次对 ping 的调用都使用比之前更大的 t 值。''

题解

var RecentCounter = function() {
    // 在构造函数中将队列挂载到this上
    // 就可以在所有的类方法上调用q[]队列
    this.q = [];
};
/** 
 * @param {number} t
 * @return {number}
 */
RecentCounter.prototype.ping = function(t) {
    // 每发起请求入队一次
    this.q.push(t);
    // 时间复杂度 O(n) n 就是小于t-3000 的请求个数
    while(this.q[0] < t - 3000) { // 队头是否小于 t - 3000
        this.q.shift();  // shift 踢出
    }
    // 空间复杂度 O(n)  n 最近的请求次数
    return this.q.length;
};