LeetCode678. 有效的括号字符串

98 阅读2分钟

有效的括号字符串

题目描述

678. 有效的括号字符串

给定一个只包含三种字符的字符串:*,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:

  1. 任何左括号 ( 必须有相应的右括号 )
  2. 任何右括号 ) 必须有相应的左括号 (
  3. 左括号 ( 必须在对应的右括号之前 )
  4. * 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
  5. 一个空字符串也被视为有效字符串。

示例 1:

输入: "()"
输出: True

示例 2:

输入: "(*)"
输出: True

示例 3:

输入: "(*))"
输出: True

注意:

  1. 字符串大小将在 [1,100] 范围内。

题解

假设没有*号,那么该题就是一个经典的括号序列判断问题,可以使用栈这种数据结构解决。

因为只有一种类型的括号,我们不一定真的使用栈,可以直接使用一个变量 cntcnt 来记录左括号的数量,扫描遇到左括号时 cntcnt++,遇到右括号时 cntcnt--,当过程中出现 cnt<0cnt < 0 或者扫描完整个序列后 cnt0cnt \neq 0 说明该括号序列不合法 。

加上*号后,因为*号可以被当做左/右括号或者空字符使用,我们就不能用一个变量来表示左括号的数量,因为数量是不确定的,而是用一个区间表示左括号的数量。

lowlow 表示左括号数量最小值,highhigh表示左括号数量最大值,初始值都为 00

同样的扫描整个序列,

当遇到左括号时,lowlow++,highhigh++,

当遇到右括号时,lowlow--,highhigh--,

当遇到 * 时:

  • * 取左括号:lowlow++,highhigh++,
  • * 取右括号:lowlow--,highhigh--,
  • * 取空,low,highlow,high 不变
  • 上面三种情况取交集,lowlow--,highhigh++
class Solution {
public:
    bool checkValidString(string s) {
        int low = 0, high = 0;
        for (auto c : s) {
            if (c == '(') low++, high++;
            else if (c == ')') low--, high--;
            else low--, high++;
            // 控制low最小值为0
            low = max(0, low);
            if (low > high) return false;
        }
        return low == 0;
    }
};