题目:给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:1.左括号必须用相同类型的右括号闭合 2.左括号必须以正确的顺序闭合。
翻译一下题目,即:每一对括号里的内容都必须对称。
最初思路是从左到右遍历,找到和当前括号闭合的另一半后判断是否是正确闭合。然后发现这种方法无法判断一对括号里的内容是否对称。
正确思路是利用哈希表(键值对,可理解为js里的对象)+栈,从里到外判断。左括号为哈希表的键,右括号为值,遍历时发现左括号(哈希表中存在该键)就把它unshift进栈,发现右括号就通过哈希表和当前栈顶元素比对,比对成功就把该栈顶元素shift出去,失败则返回false。最后判断一下stack里有没有剩下多余的左括号即可。
var isValid = function (s) {
let map={
'(':')',
'[':']',
'{':'}',
}
let stack=[]
for(let i=0;i<s.length;i++){
if(map[s[i]]){ //左括号
stack.unshift(s[i]) //压入栈顶
}else{ //右括号
if(map[stack[0]]!==s[i]){ //该右括号与栈顶左括号不匹配
return false
}else{ //匹配
stack.shift() //出栈
}
}
}
if(stack.length!==0) return false //存在多余的左括号
return true
};
不想用哈希表还有另一种方法。思想是一样的,只不过把识别左括号和判断右括号与栈顶是否匹配这两件事直接放到了if条件里:
var isValid = function (s) {
let stack=[]
for(let i=0;i<s.length;i++){
if(['(','[','{'].includes(s[i])){ //左括号
stack.unshift(s[i])
}else{ //右括号
if(['()','[]','{}'].includes(stack[0]+s[i])){ //该右括号与栈顶左括号匹配
stack.shift()
}else{
return false
}
}
}
if(stack.length!==0) return false
return true
};
个人还是更喜欢哈希表的,更直观一些