LeetCode系列记录我学习算法的过程。
持续创作,加速成长!这是我参与「掘金日新计划 6 月更文挑战」的第 19 天,点击查看活动详情
题目
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
示例:
输入: s = "()"
输出: true
输入: s = "()[]{}"
输出: true
输入: s = "(]"
输出: false
输入: s = "([)]"
输出: false
提示
1 <= s.length <= 104s仅由括号'()[]{}'组成
思路
这题被标为容易,看了下也确实不难,利用一个数组存储未闭合的左括号,然后遍历字符串抵消,最后判断数组长度即可
- 定义两个对象分别存储左括号和右括号的值映射,同类括号值一致
- 定义数组
res存储未闭合的左括号 - 遍历字符串
s,如果当前字符为左括号,存入数组第一项 - 如果当前字符为右括号,且没有未闭合的左括号,返回
false - 如果
res第一项与当前字符对应的值相同,则删除第一项 - 如果值不同,返回
false
代码实现
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
// 左括号对应的值
const left = { '(': 1, '{': 2, '[': 3 }
// 右括号对应的值
const right = { ')': 1, '}': 2, ']': 3 }
// 存储未被关闭的左括号
const res = []
// 遍历字符串s
for(let c of s) {
// 如果当前为右括号
if(right[c]) {
// 判断是否有未闭合的左括号,无则返回 false
if(!res.length) return false
// 有且最近的一个未闭合左括号与当前右括号对应,则消除该左括号
if(left[res[0]] === right[c]) {
res.shift()
} else {
// 反之不对应则返回false
return false
}
} else {
// 当前为左括号,则存入 res
res.unshift(c)
}
}
// 最后判断是否还有未闭合的左括号
return !res.length
};
优化
看了几种其他的解法,也记录一下吧
// 解法一
var isValid = function(s) {
if(s.length % 2 !== 0) return false
// 映射
const map = new Map([[')', '('], ['}', '{'], [']', '[']])
// 存储未被关闭的左括号
const res = []
// 遍历字符串s
for(let c of s) {
// 如果当前为右括号
if(map.get(c)) {
// 判断是否有未闭合的左括号,无则返回 false
if(!res.length) return false
// 有且最近的一个未闭合左括号与当前右括号对应,则消除该左括号
if(map.get(c) === res[0]) {
res.shift()
} else {
// 反之不对应则返回false
return false
}
} else {
// 当前为左括号,则存入 res
res.unshift(c)
}
}
// 最后判断是否还有未闭合的左括号
return !res.length
};
// 解法二
var isValid = function(s) {
// 存储未被关闭的左括号
const res = []
// 遍历字符串s
for(let c of s) {
switch(c) {
case '(':
case '{':
case '[':
res.unshift(c)
break
case ')':
if(res.shift() !== '(') return false
break
case '}':
if(res.shift() !== '{') return false
break
case ']':
if(res.shift() !== '[') return false
break
}
}
// 最后判断是否还有未闭合的左括号
return !res.length
};