20. 有效的括号
讲完了栈实现队列,队列实现栈,接下来就是栈的经典应用了。
大家先自己思考一下 有哪些不匹配的场景,在看视频 我讲的都有哪些场景,落实到代码其实就容易很多了。
题目
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
输入:s = "()"
输出:true
答案
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
const enumObj = {
'(': ')',
'{': '}',
'[': ']',
};
const arr = [];
for (item of s) {
if(item === '(' || item ==='{' || item ==='[') {
arr.push(enumObj[item]);
} else {
if (arr.pop() !== item) return false;
}
}
return !arr.length;
};
1047. 删除字符串中的所有相邻重复项
栈的经典应用。
要知道栈为什么适合做这种类似于爱消除的操作,因为栈帮助我们记录了 遍历数组当前元素时候,前一个元素是什么。
题目
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
答案
/**
* @param {string} s
* @return {string}
*/
var removeDuplicates = function(s) {
const stack = [];
for(item of s) {
if (stack[stack.length - 1] === item) stack.pop();
else stack.push(item);
}
return stack.join('');
};
150. 逆波兰表达式求值
本题不难,但第一次做的话,会很难想到,所以先看视频,了解思路再去做题
知识点 - Math
- Math.floor(dat) 作用:对目标数据向下取整
- Math.ceil(dat) 作用:对目标数据向上取整
- Math.trunc(dat) 作用:直接截断小数并丢弃小数部分,保留整数部分
- Math.round(dat) 作用:四舍五入
- Math.random() 作用:获取0~1之间的随机数
题目
输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
思路
要注意,使用除法可能会存在小数点,要做取整,取整时还要考虑到正数负数的问题。可以直接用 Math.trunk
答案
/**
* @param {string[]} tokens
* @return {number}
*/
var evalRPN = function(tokens) {
const getRes = function(num1, num2, symbol) {
switch(symbol) {
case '+':
return Number(num2) + Number(num1);
case '-':
return Number(num2) - Number(num1);
case '*':
return num2 * num1;
case '/':
return Math.trunc(num2 / num1);
// const res = num2 / num1;
// return res >= 0 ? Math.floor(res) : Math.ceil(res);
};
};
const stack = [];
for (item of tokens) {
if (['+', '-', '*', '/'].includes(item)) stack.push(getRes(stack.pop(), stack.pop(), item));
else stack.push(item);
}
return stack[0];
};