代码随想录算法营DAY11 | 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值
20. 有效的括号
题目链接: 20. 有效的括号
思路:
第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false
第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false
第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false
那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了。
但还有一些技巧,在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!
代码:
//map写法
var isValid = function(s) {
const stack = [];
let map={
'(':')',
'[':']',
'{':'}'
}
for(const x of s){
if(x in map) {
stack.push(x);
continue;
}
if(map[stack.pop()]!==x) return false;
}
return !stack.length;
};
//ifelse写法
var isValid = function (s) {
if(s.length % 2 !== 0) return false; // s的长度为奇数,一定不匹配
const stack = []; // 定义数组stack模拟栈
for (let i = 0; i < s.length; i++) { // 遍历字符串,遇到左括号向栈中插入对应的右括号
if(s[i] === "(") stack.push(")");
else if(s[i] === "[") stack.push("]");
else if(s[i] === "{") stack.push("}");
// s[i]与弹出的括号对比,如果不匹配则返回false
else if(s[i] !== stack.pop()) return false;
}
// 第一种情况:遍历之后如果不为空 返回false,为空返回true
return stack.length === 0;
};
总结
1.一个细节,js里空数组pop的时候会返回undefined,此时右括号多余,用!==比较的话一定不相等,返回false。
2.先分类讨论清楚不匹配的情况再写代码。
1047. 删除字符串中的所有相邻重复项
题目链接: 1047. 删除字符串中的所有相邻重复项
思路:
匹配问题想到用栈,遍历数组,比较新元素和栈顶元素是否相同,如果相同则弹出栈顶元素,不同则放入新元素,最后返回字符串。
代码:
var removeDuplicates = function(s) {
const stack = [];
let i =0;
stack.push(s[i]);
for(i=1;i<s.length;i++){
let tmp=stack.pop();
if(s[i]===tmp) continue;
else {
stack.push(tmp);
stack.push(s[i]);
}
}
return stack.join('');
};
150. 逆波兰表达式求值
题目链接: 150. 逆波兰表达式求值
思路:
1.字符串数组首先要注意先强制转换为number对象,如果不是数字会返回nan
2.若为运算符,则弹出两个数字进行运算,并存储进栈
3.若为数字,则直接入栈
4.最后返回栈底数字
代码:
var evalRPN = function(tokens) {
const stack = [];
for(const token of tokens){
if(isNaN(Number(token))){
const n2=stack.pop();
const n1 = stack.pop();
switch(token){
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(token));
}
}
return stack[0];
};
问题:
这里的向零截取是什么意思?除法那里为什么要那样写?
答:|0的意思就是向0截取,不能写Math.floor()是因为可能有负数,负数向0截取应该用Math.ceil()
补充知识点:js中&,&&,|,||的用法
感想总结
js语法遇到不懂的要及时查,栈和队列的题最好画图想清楚思路再写代码。