20. 有效的括号
思路:
第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false
第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false
第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false
代码实现
var isValid = function (s) {
const stack = [];
const map = {
"(": ")",
"[": "]",
"{": "}"
}
for (const x of s) {
console.log(x)
if (x in map) {
stack.push(x)
continue
}
// console.log(map[stack.pop()])
if (map[stack.pop()] !== x) {
return false
}
}
return !stack.length;
}
1047. 删除字符串中的所有相邻重复项
思路:
我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢?
所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。
代码实现:
var removeDuplicates = function (s) {
const stack = []
for (let i of s) {
if (i === stack[stack.length - 1]) {
stack.pop()
} else {
stack.push(i)
}
}
return stack.join('')
}
150. 逆波兰表达式求值
思路:
逆波兰表达式相当于是二叉树中的后序遍历。 大家可以把运算符作为中间节点,按照后序遍历的规则画出一个二叉树。
但我们没有必要从二叉树的角度去解决这个问题,只要知道逆波兰表达式是用后序遍历的方式把二叉树序列化了,就可以了。
代码实现:
var evalRPN = function (tokens) {
const stack = []
for (const s of tokens) {
if (isNaN(Number(s))) {
const n2 = stack.pop()
const n1 = stack.pop()
switch (s) {
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 {//如果是数字就推入栈中
stack.push(Number(s))
}
}
return stack[0]
};