Leetcode - 括号验证

254 阅读2分钟

这是我参与更文挑战的第1天,活动详情查看更文挑战

问题描述

Given a string containing only three types of characters: '(', ')' and '*', write a function to check whether this string is valid. We define the validity of a string by these rules:

给定一个只包含三种类型字符的字符串:'('')''*', 编写一个函数来检查该字符串是否有效。 我们通过以下规则定义字符串的有效性:

  1. Any left parenthesis '(' must have a corresponding right parenthesis ')'.任何左括号 '('必须有一个相应的右括号')'

  2. Any right parenthesis ')' must have a corresponding left parenthesis '('.任何右括号 ')' 必须有一个相应的左括号'('

  3. Left parenthesis '(' must go before the corresponding right parenthesis ')'.左括号'(' 必须在相应的右括号 ')' 之前

  4. '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string.*可以被视为单个右括号')'或单个左括号'('空字符串

  5. An empty string is also valid.空字符串也有效

Example 1:

**Input**: "()"
**Output**: True

Example 2:

**Input**: "(*)"
**Output**: True

Example 3:

**Input**: "(*))"
**Output**: True

Note The string size will be in the range [1, 100].字符串的长度范围为 [1, 100]

解题思路

用一个set集合来记录这个表达式中左括号能比右括号多的个数。

  • 遇到左括号,集合里面的每个元素应该+1

  • 遇到右括号,当集合里元素>0时,-1

  • 如果遇到*,应该+1-1或者不运算。

  • 看最后这个集合能否包含0,即左括号的个数等于右括号的个数。

代码

Python 版本

class Solution(object):
    def checkValidString(self, s):
        """
        :type s: str
        :rtype: bool
        """
        old_set = set([0])
        for c in s:
            new_set = set()
            if c == '(':
                for t in old_set:
                    new_set.add(t + 1)
            elif c == ')':
                for t in old_set:
                    if t > 0:
                        new_set.add(t - 1)
            elif c == '*':
                for t in old_set:
                    new_set.add(t + 1)
                    new_set.add(t)
                    if t > 0:
                        new_set.add(t - 1)
            old_set = new_set
        return 0 in old_set

C++版本

class Solution 
{
public:
    bool checkValidString(string s)
    {
        stack<int> left, star;
        for (int i = 0; i < s.length(); i++)
        {
            if (s[i] == '*')
                star.push(i);
            else if (s[i] == '(')
                left.push(i);
            else
            {
                if (left.empty() == false)
                    left.pop();
                else if (star.empty() == false)
                    star.pop();
                else
                    return false;
            }
        }

        while (left.empty() == false && star.empty() == false)
        {
            if (star.top() < left.top())
                return false;
            else
            {
                left.pop();
                star.pop();
            }
        }
        return left.empty() == true;
    }
};