文章目录
前言
从2022年12月15日左右开始看代码随想录中的栈与队列章节,到现在为止也算是一刷过了一遍代码随想录中的栈与队列章节,特此写一篇博客记录一下
一、用栈实现队列(力扣232)
1. 思路
首先需要明确的是,栈是先入后出,队列是先入先出,那么通过栈来实现队列的先入先出的操作,需要两个栈,其中一个是输入栈,一个是输出栈
在此题里需要实现队列的四个函数:push,pop,peek以及empty
- 双栈演示可以发现,对于push来讲,即只需要在stack_in中push一个元素即达到要求
- 对于pop弹出队列开头元素操作,其实也就是对于stack_out中的栈顶元素进行弹出即完成操作(如果stack_out没有元素就需要将stack_in中的元素全部移过来)
- 对于peek(返回队列开头元素但不弹出),其实和pop差不多的操作性质
- empty只需要判断两个栈是否都为空即可
2. 代码实现(js)
代码如下:
var MyQueue = function() {
this.stackIn = [];
this.stackOut = [];
};
/**
* @param {number} x
* @return {void}
*/
MyQueue.prototype.push = function(x) {
this.stackIn.push(x)
};
/**
* @return {number}
*/
MyQueue.prototype.pop = function() {
let size = this.stackOut.length
if(size) {
return this.stackOut.pop()
}
while(this.stackIn.length) {
this.stackOut.push(this.stackIn.pop())
}
return this.stackOut.pop()
};
/**
* @return {number}
*/
MyQueue.prototype.peek = function() {
let p
let size = this.stackOut.length
if(size) {
return this.stackOut[this.stackOut.length-1]
}
while(this.stackIn.length) {
this.stackOut.push(this.stackIn.pop())
}
return this.stackOut[this.stackOut.length-1]
};
/**
* @return {boolean}
*/
MyQueue.prototype.empty = function() {
if(this.stackOut.length==0 && this.stackIn.length == 0) {
return true
}
return false
};
/**
* Your MyQueue object will be instantiated and called as such:
* var obj = new MyQueue()
* obj.push(x)
* var param_2 = obj.pop()
* var param_3 = obj.peek()
* var param_4 = obj.empty()
*/
二、用队列实现栈(力扣225)
1. 思路
队列先入先出,栈先入后出,题目明确要求使用两个队列实现一个栈,实际上两个队列中的一个队列起到的作用是记录的作用。我们记两个队列为que1与que2.
用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用,把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1。
要实现push,pop,top,empty操作
- push:push其实只是将元素入que1队列即可
- pop:先把队列末尾以前的元素都移到que2中,而后将que1队列末尾的元素进行弹出,最后将que2中的元素在移回que1中
- top:访问到que1中的最末尾元素即可
- empty:que1中的长度为0就可以
2. 代码实现(js)
代码如下:
var MyStack = function() {
this.queIn = []
this.queOut = []
};
/**
* @param {number} x
* @return {void}
*/
MyStack.prototype.push = function(x) {
this.queIn.push(x)
};
/**
* @return {number}
*/
MyStack.prototype.pop = function() {
while(this.queIn.length>1) {
this.queOut.push(this.queIn.shift())
}
let ans = this.queIn.shift()
while(this.queOut.length) {
this.queIn.push(this.queOut.shift())
}
return ans
};
/**
* @return {number}
*/
MyStack.prototype.top = function() {
return this.queIn.slice(-1)
};
/**
* @return {boolean}
*/
MyStack.prototype.empty = function() {
if(this.queIn.length) {
return false
}
return true
};
/**
* Your MyStack object will be instantiated and called as such:
* var obj = new MyStack()
* obj.push(x)
* var param_2 = obj.pop()
* var param_3 = obj.top()
* var param_4 = obj.empty()
*/
三、有效的括号(力扣20)
1. 思路
括号只要是[].{},()互相配对即可,[()]合法,{}([)]不合法
因此遇到左括号进栈,遇到右括号时判断其与栈顶元素(左括号)是否配对即可
2. 代码实现(js)
代码如下:
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
let stack = []
for(let x of s) {
if(x == '(' || x == '[' || x == '{' ) {
stack.push(x)
}else{
if(x == ')' && stack.pop()!='(') {
return false
}
if(x== '}' && stack.pop()!='{') {
return false
}
if(x== ']' && stack.pop()!='[') {
return false
}
}
}
if(stack.length!=0) {
return false
}
return true
};
四、删除字符串中的所有相邻重复项(力扣1047)
1. 思路
一眼其实就可以看出来用栈进行实现,因为是两个重复的字符并进行删除,因此假如第一次遇见元素就将其压入栈中,如果下一个元素与栈顶元素一致,那么我们只需要pop出栈顶元素即可;如果第二次与第一次不一样的话就继续压栈即可,最终返回stack中的内容
2. 代码实现(js)
代码如下:
/**
* @param {string} s
* @return {string}
*/
var removeDuplicates = function(s) {
let stack = []
for(let i = 0 ; i < s.length ; i++ ){
if(stack.length && stack[stack.length-1] == s[i]) {
stack.pop()
}else {
stack.push(s[i])
}
}
// console.log(stack)
return stack.join('')
};
五、逆波兰表达式求值(力扣150)
1. 思路
只要学过数据结构那么对这个表达式都不会陌生,只需要一个数字栈即可,如果遍历到了符号字符,那么取出栈顶的两个元素进行运算,而后将运算结果压栈即可,最终数字栈只剩余一个元素作为其答案(需要注意的是除法和减法是如何进行计算的)【第二个弹出的元素作为被减数(被除数)】
2. 代码实现(js)
代码如下:
/**
* @param {string[]} tokens
* @return {number}
*/
var evalRPN = function(tokens) {
var num = []
// var sym = []
for(let i = 0 ; i <tokens.length ; i++) {
if(tokens[i]!='+'&&tokens[i]!='-'&&tokens[i]!='*'&&tokens[i]!='/') {
num.push(parseInt(tokens[i]))
}else{
let num1 = num.pop()
let num2 = num.pop()
if(tokens[i] == '/') {
let oo = num2/num1
if(oo<0) {
num.push(Math.ceil(oo))
}else{
num.push(Math.floor(oo))
}
}
if(tokens[i] == '+')
num.push(num1+num2)
if(tokens[i] == '-')
num.push(num2-num1)
if(tokens[i] == '*')
num.push(num1*num2)
}
}
// console.log(num)
return num[0]
};
六、滑动窗口(力扣239)
七、前 K 个高频元素(力扣347)
1. 思路
统计元素次数率先想到哈希表,而后进行统计前k个,涉及到排序,那么可以使用快速排序直接进行对值的排序,而后在对其对应的键按照值的大小进行统计,取出前k个的键即可
2. 代码实现(js)
代码如下:
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var topKFrequent = function(nums, k) {
let obj = new Map()
for(let i of nums) {
if(obj.has(i) == false) {
obj.set(i , 1)
}else{
pp = obj.get(i)
obj.set(i , pp+1)
}
}
var map = Array.from(obj)
map.sort((a,b)=>{
return a[1]-b[1]
})
let ans = []
for (var [key,value] of map) {
ans.push(key)
}
let arr = []
for(let i = ans.length-k ; i <ans.length ; i++) {
arr.push(ans[i])
}
return arr
}