「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。
我个人觉得要想进大厂,就必须学习了解算法和数据结构,经历了多次面试之后,也知道了算法和数据结构的重要性,所以,我也打算从今天开始,进入学习,下载了一下电子书,边看书,边跟着书的例子来敲一下代码,下面就开始总结一下对算法和数据结构的学习吧。
第十天:开始了解双端队列
双端队列
允许我们同时从前端和后端添加和移除元素的特殊队列
双端队列在现实生活中的例子也有,比如买路边摊烧烤,在排队。举个例子,我已经买好了烧烤,但我只是想要简单的加个酱,就可以直接回到最前面,让老板加个酱。排在末尾的人,如果突然有事,不想等那么久了,就可以直接离开队伍。
需要有的方法
- addFront(element):该方法在双端队列前端添加新的元素。
- addBack(element):该方法在双端队列后端添加新的元素(实现方法和 Queue 类中的 enqueue 方法相同)。\
- removeFront():该方法会从双端队列前端移除第一个元素(实现方法和 Queue 类中的 dequeue 方法相同)。\
- removeBack():该方法会从双端队列后端移除第一个元素(实现方法和 Stack 类中的 pop 方法一样)。\
- peekFront():该方法返回双端队列前端的第一个元素(实现方法和 Queue 类中的 peek 方法一样)。\
- peekBack():该方法返回双端队列后端的第一个元素(实现方法和 Stack 类中的 peek 方法一样)。
创建双端队列
class Deque {
constructor() {
this.items = {}
this.count = 0
this.lowerCount = 0
}
size() {
return this.count - this.lowerCount
}
isEmpty() {
return this.size() === 0
}
addBack(element) {
this.items[this.count] = element
this.count++
}
addFront(element) {
if (this.isEmpty()) {
this.addBack(element)
} else if (this.lowerCount > 0) {
this.lowerCount--
this.items[this.lowerCount] = element
} else {
for (let i = this.count; i > 0; i--) {
this.items[i] = this.items[i - 1]
}
this.count++
this.items[0] = element
}
}
removeBack() {
this.count--
const result = this.items[this.count]
delete this.items[this.count]
return result
}
removeFront() {
const result = this.items[this.lowerCount]
delete this.items[this.lowerCount]
this.lowerCount++
return result
}
peekFront() {
if (this.isEmpty()) return undefined
return this.items[this.lowerCount]
}
peekBack() {
if (this.isEmpty()) return undefined
return this.items[this.count - 1]
}
toString() {
if (this.isEmpty()) return ''
let text = `${this.items[this.lowerCount]}`
for (let i = this.lowerCount + 1; i < this.count; i++) {
text += `,${this.items[i]}`
}
return text
}
}
使用队列
const deque = new Deque();
console.log(deque.isEmpty()); // 输出true
deque.addBack('John');
deque.addBack('Jack');
console.log(deque.toString()); // John, Jack
deque.addBack('Camila');
console.log(deque.toString()); // John, Jack, Camila
console.log(deque.size()); // 输出3
console.log(deque.isEmpty()); // 输出false
deque.removeFront(); // 移除John
console.log(deque.toString()); // Jack, Camila
deque.removeBack(); // Camila 决定离开
console.log(deque.toString()); // Jack
deque.addFront('John'); // John 回来询问一些信息
console.log(deque.toString()); // John, Jack
用双端队列解决问题
- 回文是正反都能读通的单词、词组、数或一系列字符的序列,例如 madam 或 racecar。
function palindromeChecker(aString) {
if (aString === undefined || aString === null ||
(aString !== null && aString.length === 0)) {
return false;
}
const deque = new Deque()
let text = aString.toLocaleLowerCase().split(' ').join('')
let palindrome = true
for (let i = 0; i < text.length; i++) {
deque.addBack(text[i])
}
while (deque.size() > 1 && palindrome) {
const front = deque.removeFront()
const back = deque.removeBack()
if (front !== back) palindrome = false
}
return palindrome
}
console.log('a', palindromeChecker('a')); // true
console.log('aa', palindromeChecker('aa')); // true
console.log('kayak', palindromeChecker('kayak')); // true
console.log('level', palindromeChecker('level')); // true
console.log('Was it a car or a cat I saw', palindromeChecker('Was it a car or a cat I saw')); // true
console.log('Step on no pets', palindromeChecker('Step on no pets')); // true
console.log('reqw', palindromeChecker('reqw')); // true