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

参考:C++11新特性之基本范围的For循环(range-based-for)

(1) 只读写法

string str;
for(auto c:str){}

(2) 可修改写法

把循环中的变量定义为引用类型

string str;
for(auto &c:str){}

注意

基于范围的for对于容器map的遍历

在遍历容器的时候,auto自动推导的类型是容器的 value_type 类型,而不是迭代器,而map中的 value_typestd::pair,也就是说val的类型是std::pair类型的,因此需要使用val.first,val.second来访问数据。

for (auto &val : map)
	cout << val.first << "->" << val.second << endl;
注意一些容器类本身的约束

比如set的容器内的元素本身有容器的特性就决定了其元素是只读的,哪怕的使用了引用类型来遍历set元素,也是不能修改器元素的。

posted @ 2020-05-23 13:12  鲸90830  阅读(140)  评论(0)    收藏  举报