有效的括号
732 字
4 分钟
有效的括号
- 难度:简单
- 标签:栈、字符串
题目描述
Note
原题说明:
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
示例
- 输入:
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; }};为什么行不通?
- 嵌套问题:
([])是有效的,但它不是简单的翻转关系。 - 符号差异:括号不是数字,反转后还需要对应的方向转换(如
[变])。 - 顺序非单一性:括号可以是一对接一对的
()[]{},也可以是嵌套的({[]}),回文逻辑只能覆盖一部分极简情况。
方案二:栈(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(); }};复杂度分析
- 时间复杂度:。我们只需遍历一次包含 个字符的字符串,每个字符最多入栈一次、出栈一次。
- 空间复杂度:。在最坏情况下(所有字符都是左括号),栈的深度会达到 。
总结
- 理解栈的本质:栈是处理具有“对称性”或“后效性”问题的神器。在这个题目中,每一个右括号都在寻找它之前的“邻居”左括号。
- 边界条件:
- 字符串为空的情况。
- 只有右括号的情况(如
))})。 - 只有左括号的情况(如
(([)。
Tip
以后碰到这种“成对出现”、“最近匹配”或“消除”类的问题,第一个就要想到栈!
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
最后更新于 2025-10-04,距今已过 207 天
部分内容可能已过时
相关文章 智能推荐
1
最后一个单词的长度
算法 力扣第58题:最后一个单词的长度。从反向遍历的直观思想到双指针的精准定位,掌握字符串处理的边界细节。
2
x 的平方根
算法 力扣第69题:实现 sqrt(x)。深入理解二分查找在数值逼近中的应用,以及避免溢出的数学处理技巧。
3
相同的树
算法 力扣第100题:相同的树。利用深度优先搜索(DFS)的递归特性,优雅地判断两棵二叉树的结构与数值一致性。
4
找出字符串中第一个匹配项的下标
算法 力扣第28题:在字符串中寻找子串。从朴素的滑动窗口到 KMP 算法的“跳跃”艺术,深度剖析字符串匹配的性能巅峰。
5
最长公共前缀
算法 力扣第14题:最长公共前缀。从纵向扫描到横向缩减,再到字典树(Trie)的多种解法深度剖析。
随机文章 随机推荐