提示:努力生活,开心、快乐的一天
文章目录
20. 有效的括号
💡解题思路
数量要匹配、类型要匹配、顺序要匹配
- 借助map去定义需要遍历的数组的类型
🤔遇到的问题
- 判断右侧符号时,出错了
💻代码实现
栈+map
var isValid = function(s) {
//如果字符串是奇数,字符串肯定无效
if(s.length%2!==0) return false
let stack =[];
const map ={
'(':')',
'[':']',
'{':'}'
}
for(let i of s){
//判断左侧符号
if(i in map){
//将左侧存放到栈中
stack.push(i)
continue
}
//判断右侧符号
if(map[stack.pop()]!=i) return false
}
//是否为空
return !stack.length
};
🎯题目总结
有三种不匹配的情况
-
字符串里左方向的括号多余了
,所以不匹配 -
括号没有多余,但是 括号的类型没有匹配上
-
字符串里右方向的括号多余了,所以不匹配
1047. 删除字符串中的所有相邻重复项
💡解题思路
- 遍历字符串,将
遍历的元素与栈顶元素相比较,与栈顶元素相同,则栈顶元素弹出,与栈顶元素不同,则存入栈中
,最终栈中的元素就是最终的 数组模拟栈
进行实现双指针模拟栈
进行实现
🤔遇到的问题
- 数组模拟栈时,遍历元素需要与数组元素作比较时出错
- 双指针模拟时 ,将遍历数组存入栈中时 ,指针指向错误
💻代码实现
数组模拟栈
var removeDuplicates = function(s) {
//先进的项在最前面
let result = []
for(let i=0;i<s.length;i++){
//如果遍历的元素与数组最后一个元素不同
if(s[i]===result[result.length-1]){
//从尾部删除一个
result.pop()
}else{
//在尾部添加一个
result.push(s[i])
}
}
return result.join('')
};
双指针模拟栈
var removeDuplicates = function(s) {
let sArr = Array.from(s)
// 指向栈顶元素的下标
let top = -1
for(let i=0;i<sArr.length;i++){
// top === -1 即空栈||当前遍历的元素与栈顶元素不相等
if(top === -1||sArr[top]!==sArr[i]){
//必须top先加1,再 赋值
top++
sArr[top] = sArr[i]
}else{
//当前遍历的元素与栈顶元素相等
top--
}
}
// 栈顶元素下标 + 1 为栈的长度
sArr.length = top+1
return sArr.join('')
};
🎯题目总结
无论那种解法, 用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素
150. 逆波兰表达式求值
💡解题思路
- 什么是逆波兰表达式?
逆波兰表达式:是一种后缀表达式,所谓后缀就是指运算符写在后面
。
平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
2.使用栈解决改题:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中
。
🤔遇到的问题
- 数字入栈未 转化为Number类型
- 取栈顶两个元素时,顺序不对
💻代码实现
var evalRPN = function(tokens) {
const stack = []
for(let num of tokens){
//判断是否为运算符
if(isNaN(Number(num))){
//取栈顶两个元素,选取N2,再取N1,这对于减法与除法 很重要
let n2 = stack.pop()
let n1 = stack.pop()
//运算结果再入栈
switch(num){
case '+':
stack.push(n1+n2)
break;
case '-':
stack.push(n1-n2)
break;
case '*':
stack.push(n1*n2)
break;
case '/':
stack.push(n1/n2|0)
break
}
}else{
//非运算符直接入栈,转化为Number类型,此时为String类型
stack.push(Number(num))
}
}
//最后留在栈中的值就是最终的结果
return stack[0]
};
🎯题目总结
其实逆波兰表达式相当于是 二叉树中的后序遍历
后缀表达式对计算机来说是非常友好的
在1970年代和1980年代,惠普在其所有台式和手持式计算器中都使用了RPN(后缀表达式),直到2020年代仍在某些模型中使用了RPN
🎈今日心得
栈的题 ,万变不离其宗 ,感觉做的题多了就越来越顺手了