LeetCode_#20_有效的括号 Valid Parentheses_C++题解
20. 有效的括号 Valid Parentheses
题目描述
Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
- Note that an empty string is also considered valid.
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 注意空字符串可被认为是有效字符串。
Example 1:
Input: "()"
Output: true
Example 2:
Input: "()[]{}"
Output: true
Example 3:
Input: "(]"
Output: false
Example 4:
Input: "([)]"
Output: false
Example 5:
Input: "{[]}"
Output: true
Example 6:
Input: "("
Output: false
自解_栈
using namespace std;
#include<stack>
#include<unordered_set>
class Solution {
public:
bool isValid(string s) {
stack<char> stk;
unordered_set<char> right({')',']','}'});
for (char c:s){
if (right.find(c) == right.end()) stk.push(c); // 非右括号即入栈
else{
if (stk.empty()) return false; // 栈空即无对应左括号
if ((stk.top() == '(' && c == ')') || (stk.top() == '[' && c == ']') || (stk.top() == '{' && c == '}')) stk.pop(); // 弹出对应左括号
else return false;
}
}
if (!stk.empty()) return false; // 有多余的左括号
return true;
}
};
官方题解算法
- 初始化栈 S。
- 一次处理表达式的每个括号。
- 如果遇到开括号,我们只需将其推到栈上即可,这意味着我们将稍后处理。
- 如果我们遇到一个闭括号,那么我们检查栈顶的元素。如果栈顶的元素是一个相同类型的 左括号,那么我们将它从栈中弹出并继续处理。否则,这意味着表达式无效。
- 如果到最后我们剩下的栈中仍然有元素,那么这意味着表达式无效。
复杂度分析
- 时间复杂度:\(O(n)\),因为我们一次只遍历给定的字符串中的一个字符并在栈上进行 \(O(1)\)的推入和弹出操作。
- 空间复杂度:\(O(n)\),当我们将所有的开括号都推到栈上时以及在最糟糕的情况下,我们最终要把所有括号推到栈上。例如
((((((((((。
简化代码:C++ 11 range-based-for
(1) 只读写法
string str;
for(auto c:str){}
(2) 可修改写法
把循环中的变量定义为引用类型
string str;
for(auto &c:str){}
注意
基于范围的for对于容器map的遍历
在遍历容器的时候,auto自动推导的类型是容器的 value_type 类型,而不是迭代器,而map中的 value_type 是std::pair,也就是说val的类型是std::pair类型的,因此需要使用val.first,val.second来访问数据。
for (auto &val : map)
cout << val.first << "->" << val.second << endl;
注意一些容器类本身的约束
比如set的容器内的元素本身有容器的特性就决定了其元素是只读的,哪怕的使用了引用类型来遍历set元素,也是不能修改器元素的。

浙公网安备 33010602011771号