LeetCode 第20题:有效的括号
题目描述
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
难度
简单
题目链接
https://leetcode.cn/problems/valid-parentheses/
示例
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([])"
输出:true
提示
- 1 <= s.length <= 10⁴
- s 仅由括号 '()[]{}' 组成
解题思路
方法:栈
这是一道经典的栈应用题目。我们可以使用栈来解决这个问题,具体思路如下:
关键点:
- 遇到左括号就入栈
- 遇到右括号就与栈顶元素匹配
- 最后栈应该为空
具体步骤:
- 创建一个栈来存储左括号
- 遍历字符串:
- 如果是左括号,入栈
- 如果是右括号:
- 如果栈为空,返回false
- 如果与栈顶括号不匹配,返回false
- 如果匹配,弹出栈顶元素
- 最后检查栈是否为空
时间复杂度:O(n),其中n是字符串长度
空间复杂度:O(n),最坏情况下需要存储所有字符
代码实现
C# 实现
public class Solution {public bool IsValid(string s) {// 如果字符串长度为奇数,一定不是有效的括号if (s.Length % 2 == 1) {return false;}// 创建栈来存储左括号Stack<char> stack = new Stack<char>();// 遍历字符串foreach (char c in s) {// 如果是左括号,入栈if (c == '(' || c == '[' || c == '{') {stack.Push(c);}// 如果是右括号else {// 如果栈为空,说明没有匹配的左括号if (stack.Count == 0) {return false;}// 获取栈顶元素char top = stack.Pop();// 检查是否匹配if (c == ')' && top != '(' ||c == ']' && top != '[' ||c == '}' && top != '{') {return false;}}}// 最后检查栈是否为空return stack.Count == 0;}
}
优化版本(使用字典)
public class Solution {public bool IsValid(string s) {if (s.Length % 2 == 1) {return false;}// 使用字典存储括号对应关系Dictionary<char, char> pairs = new Dictionary<char, char> {{')', '('},{']', '['},{'}', '{'}};Stack<char> stack = new Stack<char>();foreach (char c in s) {// 如果是右括号if (pairs.ContainsKey(c)) {if (stack.Count == 0 || stack.Pop() != pairs[c]) {return false;}}// 如果是左括号else {stack.Push(c);}}return stack.Count == 0;}
}
代码详解
基本版本:
- 长度检查:
- 如果字符串长度为奇数,一定不是有效的括号
- 栈的使用:
- 使用Stack
存储左括号 - 遇到右括号时检查匹配关系
- 使用Stack
- 匹配检查:
- 检查右括号是否与栈顶左括号匹配
- 不匹配则返回false
优化版本:
- 使用字典:
- 存储右括号到左括号的映射关系
- 简化匹配逻辑
- 代码更简洁:
- 减少了if-else判断
- 逻辑更清晰
执行结果
基本版本:
- 执行用时:72 ms
- 内存消耗:37.1 MB
优化版本:
- 执行用时:68 ms
- 内存消耗:37.3 MB
总结与反思
- 这是一道经典的栈应用题目:
- 体现了栈的LIFO特性
- 处理嵌套结构的典型案例
- 优化思路:
- 使用字典简化代码
- 提前判断无效情况
- 注意事项:
- 处理栈为空的情况
- 最后检查栈是否清空
- 考虑字符串长度为奇数的情况
相关题目
- LeetCode 第32题:最长有效括号
- LeetCode 第22题:括号生成
- LeetCode 第1249题:移除无效的括号
- LeetCode 第856题:括号的分数