有效的括号

732 字
4 分钟
有效的括号

题目链接:20. 有效的括号 - 力扣(LeetCode)

  • 难度:简单
  • 标签:栈、字符串

题目描述#

Note

原题说明: 给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例#

  • 输入s = "()[]{}" -> 输出true
  • 输入s = "(]" -> 输出false
  • 输入s = "([])" -> 输出true

方案一:错误的“回文”尝试#

最初看到题目时,我产生了一个很“骚”的想法:既然括号是对称的,那是不是可以用判断回文数的逻辑来做?

我的第一版尝试(失败经验)#

class Solution {
public:
bool isValid(string s) {
if(s.empty()) return false;
string str = s.substr(s.length()/2, s.length());
string str2 = s.substr(0, s.length()/2);
reverse(str.begin(), str.end());
return str == str2;
}
};

为什么行不通?

  1. 嵌套问题([]) 是有效的,但它不是简单的翻转关系。
  2. 符号差异:括号不是数字,反转后还需要对应的方向转换(如 [])。
  3. 顺序非单一性:括号可以是一对接一对的 ()[]{},也可以是嵌套的 ({[]}),回文逻辑只能覆盖一部分极简情况。

方案二:栈(Stack)的经典应用(推荐)#

括号匹配是**栈(Stack)**数据结构的教科书级应用。栈具有 后进先出 (LIFO) 的特性,这完美契合了“最后进去的左括号必须最先被抵消”的原则。

源码实现#

#include <stack>
#include <string>
using namespace std;
class Solution {
public:
bool isValid(string s) {
stack<char> st;
for (char c : s) {
// 如果是左括号,直接入栈
if (c == '(' || c == '[' || c == '{') {
st.push(c);
}
// 如果是右括号,检查栈顶是否匹配
else {
if (st.empty()) return false; // 栈为空却收到了右括号,无效
char top = st.top();
st.pop();
if ((c == ')' && top != '(') ||
(c == ']' && top != '[') ||
(c == '}' && top != '{')) {
return false;
}
}
}
// 最后必须保证栈内所有左括号都被抵消了
return st.empty();
}
};

复杂度分析#

  • 时间复杂度O(n)O(n)。我们只需遍历一次包含 nn 个字符的字符串,每个字符最多入栈一次、出栈一次。
  • 空间复杂度O(n)O(n)。在最坏情况下(所有字符都是左括号),栈的深度会达到 nn

总结#

  • 理解栈的本质:栈是处理具有“对称性”或“后效性”问题的神器。在这个题目中,每一个右括号都在寻找它之前的“邻居”左括号。
  • 边界条件
    • 字符串为空的情况。
    • 只有右括号的情况(如 ))})。
    • 只有左括号的情况(如 (([)。
Tip

以后碰到这种“成对出现”、“最近匹配”或“消除”类的问题,第一个就要想到

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

有效的括号
https://firefly-7a0.pages.dev/posts/leetcode_notes/20valid-parentheses/
作者
lonelystar
发布于
2025-10-04
许可协议
CC BY-NC-SA 4.0
最后更新于 2025-10-04,距今已过 207 天

部分内容可能已过时

评论区

Profile Image of the Author
LonelyStar
Hello, I'm LonelyStar.
公告
欢迎来到我的博客!
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
119
分类
11
标签
346
总字数
226,548
运行时长
0
最后活动
0 天前

目录