「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」
前言
来了来了,它来了,经常会被问到的一个经典题型,判断给定的括号字符串是不是有效的,我们的括号字符串当然是只包含()[]{}这三种括号啦,同样,今天还是栈的话题,不过会提供两种解题思路哟。
题目描述
20. 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/va… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
- 什么样的括号字符串为有效?什么又为无效?
例如:"()"、"()[]{}"、"{[]}"这样的是有效,"(]"、"([)]"这样又交叉的视为无效 - 巧妙利用栈结构
如果我们让括号字符按顺序入栈,遇到成对的有效括号就让它们出栈,到最后会留下一个空栈,如果括号字符串是无效的,那么肯定有没配对成功的留在栈里 - 配对协助工具
你可以直接暴力if...else,也可以用switch...case,当然也可以搭配Es6新出的集合类型,利用它的键值对存储机制。 - 配对规则
1)首先我们需要遍历括号字符串的括号字符,那么直接用for...of即可;
2)如果是左括号'('、'['、'{',直接执行入栈操作;
3)如果是右括号且栈内没有元素了,那说明前面没有能与该右括号配对的的左括号了,说明当前是无效括号字符串,返回false;
4)如果是右括号且栈内有元素,还需判断栈顶元素是否能与当前右括号配对,如果没有能配对的,则说明不同类型的括号交叉了,说明当前是无效括号字符串,返回false; 5) 如果是右括号且能成功配对,那就让栈顶能配对的元素出栈即可; 6)最后如果栈为空则说明该括号字符串有效,否则,无效。
开始解题
1、用switch...case + 栈
var isValid = function(s) {
let stack = [];
for(char of s) {
switch(char) { // 遇到右括号,if判断中直接判断栈顶pop元素是否能达成同类型括号配对,
case ')': // 包含了空栈的情况,也是无效配对,不能就返回false说明当前不是有效括号字符串
if(stack.pop() !== '(') return false;
break;
case ']':
if(stack.pop() !== '[') return false;
break;
case '}':
if(stack.pop() !== '{') return false;
break;
default: // 默认情况是遇到左括号的条件直接入栈
stack.push(char);
}
}
return !stack.length;
};
2、用Map + 栈
let map = new Map([ // 使用嵌套数组,右括号为键,左括号为值的键值对方式初始化Map映射
[')','('],
[']','['],
['}','{'],
])
let stack = [];
for(char of s) {
if(map.has(char)) { // 如果当前括号字符能匹配上以右括号为键的Map映射时
if(!stack.length || stack[stack.length-1] !== map.get(char)){
return false; // 栈为空或栈顶元素不能完成配对说明当前是无效括号字符串
}
stack.pop();
}else { // else的情况就是遇到左括号即入栈
stack.push(char);
}
}
return !stack.length;
};