一、题目描述(清晰易懂版)
给定一个只包含三种括号的字符串 s,括号类型分别是 '('、')'、'{'、'}'、'['、']',要求判断这个字符串是否是「有效括号」。
有效括号需要同时满足 3 个条件,缺一不可:
- 左括号必须用「相同类型」的右括号闭合(比如
'('不能用']'闭合); - 左括号必须以「正确的顺序」闭合(比如
"({})"有效,但"({)}"无效,因为括号嵌套顺序乱了); - 每个右括号都有一个「对应的相同类型」的左括号(比如
")"单独出现一定无效)。
举几个例子帮助理解:
- 输入
"()"→ 输出true(最简单的有效括号); - 输入
"()[]{}"→ 输出true(三种括号依次闭合,顺序正确); - 输入
"(]"→ 输出false(左括号类型与右括号不匹配); - 输入
"([)]"→ 输出false(嵌套顺序错误); - 输入
"{"→ 输出false(只有左括号,没有对应右括号)。
二、解题思路:为什么用「栈」?
这道题的核心痛点是「括号的嵌套顺序」——后出现的左括号,需要先被闭合(类似'先进后出'的逻辑),而栈这种数据结构,恰好完美匹配「先进后出」的特性。
基于栈的解题思路,拆解为 4 步:
- 初始化一个空栈,用于存储「未闭合的左括号」;
- 创建一个映射表(对象),存储「右括号对应的左括号」(比如
')'对应'('),这样后续遇到右括号时,能快速找到它需要匹配的左括号; - 遍历字符串的每一个字符:
- 如果当前字符是「左括号」(
'('、'['、'{'),就把它压入栈中; - 如果当前字符是「右括号」,就检查栈是否为空,以及栈顶元素是否是它对应的左括号:
- 如果栈为空 → 说明没有未闭合的左括号,却出现了右括号,直接返回
false; - 如果栈顶元素不是对应的左括号 → 匹配失败,返回
false; - 如果匹配成功 → 把栈顶的左括号弹出(表示这个左括号已经被成功闭合)。
- 如果栈为空 → 说明没有未闭合的左括号,却出现了右括号,直接返回
- 如果当前字符是「左括号」(
- 遍历结束后,检查栈是否为空:
- 栈为空 → 所有左括号都被闭合,返回
true; - 栈不为空 → 还有未闭合的左括号,返回
false。
- 栈为空 → 所有左括号都被闭合,返回
三、完整解题代码(TypeScript 版)
function isValid(s: string): boolean {
// 1. 初始化空栈,存储未闭合的左括号
const stack = [];
// 2. 建立右括号与左括号的映射关系,key 是右括号,value 是对应的左括号
: { [: ]: } = {
: ,
: ,
:
};
( i = ; i < s.; i++) {
: = s[i];
(char === || char === || char === ) {
stack.(char);
} {
(stack. === || stack[stack. - ] !== map[char]) {
;
}
stack.();
}
}
stack. === ;
}


