题目描述
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
提示:
1 <= s.length <= 10^4
s 仅由括号 ‘()[]{}’ 组成
示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false
示例 4:
输入:s = “([)]”
输出:false
示例 5:
输入:s = “{[]}”
输出:true
解题思路
首先我们还是先从特殊情况开始,由“提示”可知,s 是包含‘()[]{}’这六个字符的长度为1-10^4的字符串,如果 s 的长度为奇数,那么这个字符串肯定不符合条件,因为符合条件的括号一定是成对出现的。
接着我们考虑s的长度为偶数情况,首先第一个字符一定是左括号,从第二个开始可能是左括号也可能是右括号,如果是右括号,那么在这个右括号旁边一定有一个和它对应的左括号,只有这样才能符合条件,之后的每个位置的情况都跟第二个一样。
然后我们考虑怎么利用这个特性去检查 s 是否符合条件。我们可以利用一个数组用来存储在遍历 s 过程中,在没有遇到任何右括号之前遇到的左括号,而一旦遇见右括号,就去找这个数组中最后一个字符(即最后被放进去的那个左括号),看看 ta 们是不是成对的括号,如果不是,则直接返回 false ,即 s 不符合规则;如果是,则将这个与 ta 配对的左括号从数组中拿出来,让 ta 们两个领结婚证去吧,别耽误我解题。然后继续往下面走,直到 s 遍历完或 数组里面没有左括号了但是我们却遇见了一个右括号,如果是前者,证明我们已经完成了遍历,只要看数组里面还有没有左括号,有,则证明这些是剩下来的单身狗,不符合规则,没有,证明所有的右括号都找到了 ta 的左括号,完美的结局,返回 true 符合规则;如果是后者,证明这个右括号是多出来的单身狗,直接返回 false 即可。
以下是我画的思维导图:
代码
function isValidBracket(s) {
if(s.length % 2 === 1) return false
let flag = true
let store = []
let index = 0
while(flag && index < s.length) {
let bracket = s.charAt(index++)
if(convert(bracket)) { // 如果是左括号
store.push(bracket)
} else { // 如果是右括号
let storeBracket = store[store.length - 1]
if (bracket === convert(storeBracket)) { // 如果成对,则将左括号弹出
store.pop()
} else {
flag = false
}
}
}
if(store.length > 0) {
flag = false
}
return flag
}
function convert(char) {
switch(char) {
case '(':
return ')'
case '[':
return ']'
case '{':
return '}'
default:
return undefined
}
}
题解之后
看了几点之后,对代码做了一些细微的处理。
1、使用对象来保存括号之间的成对关系
2、为了预防数组为空时调用pop方法报错,在数组预置了个元素’?‘
function isValidBracket(str) {
if(str.length % 2 === 1) return false
const obj = {
'(': ')',
'[': ']',
'{': '}'
}
let flag = true
let store = ['?']
let index = 0
while(flag && index < str.length) {
let bracket = str[index++]
if(obj[bracket]) { // 如果是左括号
store.push(bracket)
} else { // 如果是右括号
let storeBracket = store.pop()
// 如果第一个为右括号,或不成对,则将直接返回结果
if (bracket !== obj[storeBracket]) {
return false
}
}
}
return store.length === 1
}
总结: 其实可以悄悄的告诉你,第一、第二种方法在内存方面的消耗一样,但是第一种执行时间更短。
写在最后: 如果错误,欢迎指正