20. 有效的括号 - 力扣(LeetCode)
发布:2021年7月31日24:02:31
问题描述及示例
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false
示例 4:
输入:s = “([)]”
输出:false
示例 5:
输入:s = “{[]}”
输出:true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
提示:
1 <= s.length <= 104
s 仅由括号 ‘()[]{}’ 组成
我的题解(栈)
更新:2021年7月31日00:12:28
这道题思路不算复杂,我一开始是想取巧,想着能不能将输入的s
进行reverse
操作,然后将操作结果与原来的s
做比较,如果一样的话就返回true
,否则返回false
。但是很快,我看到了第2个示例,发现这样不行。没过多久,我又想到了用栈的思想。
总体思路就是利用辅助栈matchStack
存储origin
中的右括号(当然存左括号也行,相应的地方也得改就是了),如果origin
的栈顶元素为右括号,则直接压入matchStack
;如果origin
的栈顶元素为左括号,则需要判断该元素是否和matchStack
的栈顶元素相匹配,如果左右括号匹配成功,则将matchStack
中的栈顶元素弹出(突然想到,其实此时就可以返回false
结果了,这也能在一定程度上提高一点效率)。将origin
中的所有括号都遍历之后,如果两个栈均为空,说明所有括号都有相应的符合规则的匹配,当且仅当这种情况下可以返回true
,其他情况均返回false
。
大致过程可看下方示意图。
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function (s) {
// 先将原始字符串转化为字符数组以便后续进行内容修改(字符串本身并不支持)
let origin = s.split('');
// 由于是将数组末尾作为栈的出口(栈顶),所以设置一个变量来存储所有可能的右括号
let rightBrackets = [')', '}', ']'];
// 下面这个判断其实可有可无,我觉得加上之后多少可以提高效率,毕竟做了提前返回的操作
// 如果字符的第一位就是一个右括号或者字符的长度为奇数,则必然不能完全匹配,可提前返回
if (rightBrackets.includes(origin[0]) || origin.length % 2 !== 0) {
return false;
}
// matchStack用作匹配的辅助栈
let matchStack = [];
// 注意下面的i的初始值和结束条件,这是题目中比较关键的地方,j用于动态指向origin栈顶
for (let i = 0, len = origin.length, j = len - 1; i < len; i++, j--) {
// 若origin栈顶为右括号,则将其压入matchStack以备后用,
// 同时将origin栈顶元素弹出,并用continue提前结束本次循环进入下一次循环
if (rightBrackets.includes(origin[j])) {
matchStack.push(origin[j]);
origin.pop();
continue;
}
// 若matchStack栈顶元素与origin栈顶元素相互匹配,则将这对括号同时分别从两个栈中删除
if (matchStack[matchStack.length - 1] === matchTheHalf(origin[j])) {
matchStack.pop();
origin.pop();
} else {
// 更新:2021年7月31日01:55:32
return false;
}
}
// 将origin栈里的元素全部遍历完后,当且仅当两个栈里都没有元素了(都匹配完了)
// 说明 s 是符合括号匹配规则的字符串,返回true
if (matchStack.length === 0 && origin.length === 0) {
return true;
}
// 除上面所说的的其他情况,均为不符合括号匹配规则,返回false
return false;
// matchTheHalf用于返回与某个左括号相匹配的右括号
function matchTheHalf(bracket) {
if (bracket === '(') return ')';
if (bracket === '{') return '}';
if (bracket === '[') return ']';
}
};
提交记录
91 / 91 个通过测试用例
状态:通过
执行用时: 76 ms,在所有 JavaScript 提交中击败了82.80%的用户
内存消耗: 37.9 MB,在所有 JavaScript 提交中击败了83.93%的用户
时间:2021年7月31日00:00:02
更新:2021年7月31日01:55:32
在上面的代码中加入了一个 else 语句分支,发现时间性能提高了不少
执行用时:64 ms, 在所有 JavaScript 提交中击败了97.92%的用户
内存消耗:38.8 MB, 在所有 JavaScript 提交中击败了49.80%的用户
官方题解
更新:2021年7月29日18:43:21
因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。
更新:2021年7月31日24:11:01
【更新结束】
有关参考
暂无