javascript版数据结构之队列(附:leetCode 933)

192 阅读2分钟

1、概念

  队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。(ps: 来源百度百科)

image.png

2、js中的队列

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

// 创建一个数组模拟队列
const queue = [];
// 入队
queue.push(1); // queue: [1]
queue.push(2); // queue: [1,2]
// 出队
const first = queue.shift() // stack: [2]
const second = queue.shift() // stack: []

3、队列的应用场景

  • 需要先进先出的场景。
  • 比如:食堂排队打饭、js异步中的任务队列、计算最近请求次数

js是单线程的, 主线程在执行过程中遇到了异步任务,就发起函数或者称为注册函数,通过event loop线程通知相应的工作线程(如ajax,dom,setTimout等),同时主线程继续向后执行,不会等待。等到工作线程完成了任务,eventloop线程会将消息添加到消息队列中,如果此时主线程上调用栈为空就执行消息队列中排在最前面的消息,依次执行。新的消息进入队列的时候,会自动排在队列的尾端。

image.png

4、leetCode

leetCode 933. 最近的请求次数

写一个 RecentCounter 类来计算特定时间范围内最近的请求。

  • 请你实现 RecentCounter 类:
  • RecentCounter() 初始化计数器,请求数为 0 。
  • int ping(int t) 在时间 t 添加一个新请求,其中 t 表示以毫秒为单位的某个时间,并返回过去 3000 毫秒内发> >生的所有请求数(包括新请求)。确切地说,返回在 [t-3000, t] 内发生的请求数。 保证 每次对 ping 的调用都使用比之前更大的 t 值。
var RecentCounter = function() {
    this.q = []; // 定义一个队列
};

/** 
 * @param {number} t
 * @return {number}
 */
RecentCounter.prototype.ping = function(t) {
    // 发生请求入队
    this.q.push(t);
    // 判断入队后 队头到队尾的范围是否在 [t-3000, t] 外
    // 如果在范围外  则队头的消息直接出队
    while (this.q[0] < t - 3000) {
        this.q.shift();
    }
    // 当前队列长度即为发生的请求次数
    return this.q.length;
};

/**
 * Your RecentCounter object will be instantiated and called as such:
 * var obj = new RecentCounter()
 * var param_1 = obj.ping(t)
 */