船长表情包镇楼
队列
- 队列是连续的存储区,可以存储一系列的元素。是FIFO(先入先出,FirstIn-First-Out)结构
- 队列通常具有头尾指针(左闭右开区间),头指针指向第一个元素,尾指针指向最后一个元素的下一位
- 队列支持(从队尾)入队(enqueue)、(从队首)出队(dequeue)操作
- 循环队列可以通过取模操作更充分地利用空间
典型应用场景
LeetCode肝题
-
- 设计循环队列
var MyCircularQueue = function(k) {
this.arr = new Array(k)
this.head = 0
this.tail = 0
this.cut = 0
};
MyCircularQueue.prototype.enQueue = function(value) {
if (this.isFull()) return false
this.arr[this.tail] = value
this.tail = (this.tail + 1) % this.arr.length
this.cut ++
return true
};
MyCircularQueue.prototype.deQueue = function() {
if (this.isEmpty()) return false
this.head = (this.head + 1) % this.arr.length
this.cut --
return true
};
MyCircularQueue.prototype.Front = function() {
if (this.isEmpty()) return -1
return this.arr[this.head]
};
MyCircularQueue.prototype.Rear = function() {
if (this.isEmpty()) return -1
return this.arr[(this.tail - 1 + this.arr.length) % this.arr.length]
};
MyCircularQueue.prototype.isEmpty = function() {
if (this.cut == 0) return true
return false
};
MyCircularQueue.prototype.isFull = function() {
if (this.cut == this.arr.length) return true
return false
};
-
- 设计循环双端队列
var MyCircularDeque = function(k) {
this.arr = new Array(k)
this.head = 0
this.tail = 0
this.cut = 0
};
MyCircularDeque.prototype.insertFront = function(value) {
if (this.isFull()) return false
this.head = (this.head - 1 + this.arr.length) % this.arr.length
this.arr[this.head] = value
this.cut ++
return true
};
MyCircularDeque.prototype.insertLast = function(value) {
if (this.isFull()) return false
this.arr[this.tail] = value
this.tail = (this.tail + 1) % this.arr.length
this.cut ++
return true
};
MyCircularDeque.prototype.deleteFront = function() {
if (this.isEmpty()) return false
this.head = (this.head + 1) % this.arr.length
this.cut --
return true
};
MyCircularDeque.prototype.deleteLast = function() {
if (this.isEmpty()) return false
this.tail = (this.tail - 1 + this.arr.length) % this.arr.length
this.cut --
return true
};
MyCircularDeque.prototype.getFront = function() {
if (this.isEmpty()) return -1
return this.arr[this.head]
};
MyCircularDeque.prototype.getRear = function() {
if (this.isEmpty()) return -1
return this.arr[(this.tail - 1 + this.arr.length) % this.arr.length]
};
MyCircularDeque.prototype.isEmpty = function() {
return this.cut == 0
};
MyCircularDeque.prototype.isFull = function() {
return this.arr.length == this.cut
};
-
- 设计前中后队列
var Node = function(val) {
this.val = val
this.next = null
this.pre = null
};
Node.prototype.insert_pre = function(p) {
p.next = this
p.pre = this.pre
this.pre && (this.pre.next = p)
this.pre = p
return
};
Node.prototype.insert_next = function(p) {
p.next = this.next
p.pre = this
this.next && (this.next.pre = p)
this.next = p
return
};
Node.prototype.delete_pre = function() {
if (!this.pre) return null
let p = this.pre
this.pre = p.pre
p.pre && (p.pre.next = this)
return
}
Node.prototype.delete_next = function() {
if (!this.next) return null
let p = this.next
this.next = p.next
p.next && (p.next.pre = this)
return
}
var deQueue = function() {
this.cut = 0
this.head = new Node(null)
this.tail = new Node(null)
this.head.next = this.tail
this.tail.pre = this.head
};
deQueue.prototype.push_back = function(val) {
this.tail.insert_pre(new Node(val))
this.cut ++
}
deQueue.prototype.push_front = function(val) {
this.head.insert_next(new Node(val))
this.cut ++
}
deQueue.prototype.pop_back = function() {
if (this.isEmpty()) return -1
const ret = this.tail.pre.val
this.tail.delete_pre()
this.cut --
return ret
}
deQueue.prototype.pop_front = function() {
if (this.isEmpty()) return -1
const ret = this.head.next.val
this.head.delete_next()
this.cut --
return ret
}
deQueue.prototype.front = function() {
return this.head.next.val
}
deQueue.prototype.pop = function() {
return this.tail.pre.val
}
deQueue.prototype.isEmpty = function() {
return this.cut == 0
}
deQueue.prototype.size = function() {
return this.cut
}
var FrontMiddleBackQueue = function() {
this.p = new deQueue()
this.q = new deQueue()
};
FrontMiddleBackQueue.prototype.pushFront = function(val) {
this.p.push_front(val)
this.update()
};
FrontMiddleBackQueue.prototype.pushMiddle = function(val) {
this.p.push_back(val)
this.update()
};
FrontMiddleBackQueue.prototype.pushBack = function(val) {
this.q.push_back(val)
this.update()
};
FrontMiddleBackQueue.prototype.popFront = function() {
let ret
if (this.p.size()) {
ret = this.p.pop_front()
} else {
ret = this.q.pop_back()
}
this.update()
return ret
};
FrontMiddleBackQueue.prototype.popMiddle = function() {
let ret
if (this.p.size() == this.q.size()) {
ret = this.p.pop_back()
} else {
ret = this.q.pop_front()
}
this.update()
return ret
};
FrontMiddleBackQueue.prototype.popBack = function() {
const ret = this.q.pop_back()
this.update()
return ret
};
FrontMiddleBackQueue.prototype.update = function() {
if (this.p.size() > this.q.size()) {
this.q.push_front(this.p.pop_back())
}
if (this.q.size() == this.p.size() + 2) {
this.p.push_back(this.q.pop_front())
}
};
-
- 最近的请求次数
var RecentCounter = function() {
this.arr = []
};
RecentCounter.prototype.ping = function(t) {
this.arr.push(t)
while(t - this.arr[0] > 3000) this.arr.shift()
return this.arr.length
};
- 面试题 17.09. 第 k 个数
var getKthMagicNumber = function(k) {
const arr = new Array(k)
let p3 = 0, p5 = 0, p7 = 0
arr[0] = 1
for(let i = 1; i < k; i++) {
let num1 = 3 * arr[p3]
let num2 = 5 * arr[p5]
let num3 = 7 * arr[p7]
let min = Math.min(num1,num2,num3)
if (min == num1) p3 ++
if (min == num2) p5 ++
if (min == num3) p7 ++
arr[i] = min
}
return arr[k-1]
};
-
- 亲密字符串
var buddyStrings = function(a, b) {
if (a.length != b.length) return false
if (b == a) return has_repeate(a)
let i = 0, j
while(a[i] == b[i]) i++
j = i + 1
while(j < a.length && a[j] == b[j]) j++
if (j == a.length) return false
if (a[i] != b[j] || a[j] != b[i]) return false
j += 1
while(j < a.length) {
if (a[j] != b[j]) return false
j++
}
return true
};
var has_repeate = function(str) {
const obj = {}
for(let i = 0; i < str.length; i++) {
obj[str[i]] = null
}
return Object.keys(obj).length < str.length
}
-
- 柠檬水找零
var lemonadeChange = function(bills) {
let obj = {
5: 0,
10: 0
}
for(let i = 0; i < bills.length; i++) {
if (bills[i] == 5) {
obj[5] ++
} else if (bills[i] == 10){
obj[10] ++
obj[5] --
} else if (bills[i] == 20){
if (obj[10]){
obj[10]--
obj[5] --
} else {
obj[5] -= 3
}
}
if (obj[5] < 0) return false
}
return true
};
-
- 煎饼排序
var pancakeSort = function(arr) {
let ret = [], ind = Array(arr.length + 1)
for(let i = 0; i < arr.length; i++) ind[arr[i]] = i
for(let i = arr.length; i >= 1; i--) {
if (ind[i] == i-1) continue
if (ind[i]) {
ret.push(ind[i] + 1)
reverse(arr, ind[i] + 1, ind)
}
if (i != 1) {
ret.push(i)
reverse(arr, i, ind)
}
}
return ret
};
var reverse = function(arr, n, ind) {
for(let i = 0, j = n - 1; i < j; i++, j--) {
[arr[i], arr[j]] = [arr[j], arr[i]]
ind[arr[i]] = i
ind[arr[j]] = j
}
}
-
- 任务调度器
图解

var leastInterval = function(tasks, n) {
let obj = {}, max = 0, num = 0
for(let i = 0; i < 26; i++) {
obj[String.fromCharCode(i+65)] = 0
}
for(let i = 0; i < tasks.length; i++) {
obj[tasks[i]] += 1
}
let arr = Object.keys(obj)
for(let i = 0; i < arr.length; i++) {
max = Math.max(obj[arr[i]], max)
}
for(let i = 0; i < arr.length; i++) {
if (obj[arr[i]] == max) num ++
}
return Math.max((max - 1) * (n + 1) + num, tasks.length)
};