Offer 驾到,掘友接招!我正在参与 2022 春招打卡活动,点击查看活动详情。
一、题目描述:
- 有效的括号-难度简单 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()" 输出:true 示例 2:
输入:s = "()[]{}" 输出:true 示例 3:
输入:s = "(]" 输出:false 示例 4:
输入:s = "([)]" 输出:false 示例 5:
输入:s = "{[]}" 输出:true
提示:
1 <= s.length <= 104 s 仅由括号 '()[]{}' 组成
二、题目和思路分析:
最最开始我想的很简单:
如果字符串有效,那么括号必定不能互相交叉
也就是说,这道题本质上是考察回文
所以判断条件为:
字符串长度为偶数
将字符串一分为二,翻转第一部分,它和第二部分完全相等
可是当我开始写代码,我发现我想的并不正确:
一分为二判断两边完全相等是错误的,左括号翻转也不会变成右括号,并且两边也不一定完全相等
于是我想了想,判断条件应该是:
每一对括号里都不能只存在其它单个的括号
每个左括号都有按顺序与之对应的右括号
可是这么想代码还是无从下手。。。
终于在我手动写了n个测试例子之后,我才明白过来:
最开始的字符必定是左括号,遇到第一个右括号,与之对应的左括号一定是前面所遇到的最后一个左括号。
这么想起来,一切就很简单起来了~
三、代码:
代码实现如下:
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
if(s.length%2 == 1){ // 如果是奇数,直接返回false
return false
}else{
let arr = [] // 记录遇到的左括号
let obj = { // 括号对应关系
'(': ')',
'[': ']',
'{': '}',
}
for(let x of s) { // 遍历s字符串
if(x in obj) { // 如果是左括号,加入到arr
arr.push(x)
continue
}
if(obj[arr.pop()] !== x){ // 如果是右括号,则取出左括号数组的最后一项看是否对应,如果不对应当前左括号的最后一项,则返回false
// pop()方法删除数组的最后一项,返回数组的最后一项,并改变原数组。
return false
}
}
return arr.length == 0 // 当数组完全被对应消除完,才算正确
}
}
四、总结:
这道题写的简,看起来也挺简单,但是做起来还是感觉有点难度,主要是规律不好把握。
所以对于这道题而言,难的不是代码的逻辑,而是解决的方法思路,即:【遇到第一个右括号,与之对应的左括号一定是前面所遇到的最后一个左括号。】
加油吧!