队列
队列是一个 先进先出 的数据结构。JavaScript 中没有栈,但可以用 Array 实现栈的所有功能
const queue = []
queue.push(1)
queue.push(2)
const item1 = queue.shift()
队列应用场景
- 需要 先进先出 (
First in First out
)的场景。日常生活中栈的应用:打印队列、食堂打饭排队、键盘打字
食堂排队打饭
- 先进先出,保证有序
JS 异步中的任务队列
- JS 是单线程,无法同时处理异步中的并发任务
- 使用任务队列先后处理异步任务
计算最近请求次数
- 有新请求就入队,3000 ms 前发出的请求出队
- 队列的长度的就是最近请求次数
933. 最近的请求次数
输入输出
写一个 RecentCounter
类来计算特定时间范围内最近的请求
RecentCounter()
初始化计数器,请求数为 0 。int ping(int t)
在时间t
添加一个新请求,其中t
表示以毫秒为单位的某个时间,并返回过去 3000- 毫秒内发生的所有请求数(包括新请求)。确切地说,返回在
[t-3000, t]
内发生的请求数。
输入:
["RecentCounter", "ping", "ping", "ping", "ping"] // 对应时间:[[], [1], [100], [3001], [3002]]
输出:
[null, 1, 2, 3, 3]
题解
- 越早发出的请求越早不在最近 3000 ms 内的请求里,满足先进先出
步骤
- 有新请求就入队,3000 ms 前发出的请求出队
- 队列的长度就是最近请求次数
var RecentCounter = function () {
this.q = []
}
RecentCounter.prototype.ping = function (t) {
this.q.push(t)
while (this.q[0] < t - 3000) {
this.q.shift()
}
return this.q.length
}
时间复杂度:O(n)
。n
是需要被踢出队的请求次数
空间复杂度:O(n)
。n
是最近请求次数
JS异步中的任务队列
setTimeout(() => console.log(1), 0)
console.log(2)
因为 JS 是单线程,每次只能处理一个事件,在执行这个任务时,如果里面有一些异步操作(ajax
、setTimeout
)会丢给 WebAPIs 执行,WebAPIs 执行完会把回调函数放入 Callback Queue
中,任务队列里代码执行完了,回调函数就会放入 JS 引擎中继续执行
思考题
ES6 封装队列
class Queue {
constructor() {
this.items = []
}
enqueue(item) {
return this.items.push(item)
}
dequeue() {
return this.items.shift()
}
size() {
return this.items.length
}
isEmpty() {
return this.items.length === 0
}
}
回文词判定
- 回文词:正读和反读都一样的词
function palChecker(s) {
const arr = s.split('')
while (arr.length > 1) {
const first = arr.shift()
const last = arr.pop()
if (first !== last) {
return false
}
}
return true
}
console.log(palChecker('radar'))