这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战
题目
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s ,判断字符串是否有效。
有效字符串需满足:
1. 左括号必须用相同类型的右括号闭合。
2. 左括号必须以正确的顺序闭合。
示例1
输入:s = "()"
输出:true
示例2
输入:s = "()[]{}"
输出:true
示例3
输入:s = "(]"
输出:false
思路
题目给的是一串只包含由特定字符的组成的字符串,判断该字符串是否符合条件
看到这道题,很容易会想到一个游戏,叫 消消乐
,符合相同状态的字符,俩俩可以抵消
那么就可以有如下思路
-
用哈希结构存储题目所给的字符,并且俩俩可以抵消(-1 + 1 = 0)
-
定义
stack
为 Array类型,初始时为空; -
遍历题目所给字符串,
-
当 遇到的是
左括号
时,将该字符推入stack
-
当
stack.length === 0
时,将当前i
位置上的字符推入stack
; -
当
stack.length !== 0
时,取出stack
末位的字符prev
,和当前i
位置上的字符比较,如果可以抵消,则进入下次遍历,否则将prev
、s[i]
依次推入stack
-
-
最后判断
stack
的长度是否为0,为0则匹配成功
特殊情况
字符串的长度若为奇数,则匹配肯定失败
若字符串的长度为0,则直接返回匹配成功
代码如下
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function (s) {
let n = s.length;
// 空字符返回true
if (n == 0) return true;
// 奇数直接返回false
if (n % 2 == 1) return false;
// 定义哈希表
let strMap = {
'{': 1,
'}': -1,
'(': 2,
')': -2,
'[': 3,
']': -3
}
let stack = [];
for (let i = 0; i < n; i++) {
let cur = s.charAt(i);
// 栈的长度为0,或者是左括号
if (!stack.length || strMap[cur] > 0) {
stack.push(cur);
continue;
}
// 取出当前栈的最后一个字符
let prev = stack.pop();
// 不匹配则将 prev 和 当前字符 cur 推入 stack
if (strMap[prev] + strMap[cur] !== 0) {
stack.push(prev);
stack.push(cur);
}
}
return stack.length === 0;
};
小结
栈的结构,先进先出,可以很好的应对本题的匹配规则;熟悉数据结构,才能有好的解法
LeetCode 👉 HOT 100 👉 删除链表的倒数第 N 个结点 - 中等题 ✅
LeetCode 👉 HOT 100 👉 删除链表的倒数第 N 个结点 - 中等题
LeetCode 👉 HOT 100 👉 电话号码的字母组合 - 中等题
✅
LeetCode 👉 HOT 100 👉 三数之和 - 中等题
✅
LeetCode 👉 HOT 100 👉 盛最多水的容器 - 中等题
✅
LeetCode 👉 HOT 100 👉 最长回文子串 - 中等题
✅
LeetCode 👉 HOT 100 👉 无重复字符的最长子串 - 中等题
✅