有效的括号字符串
题目描述
给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
- 任何左括号
(必须有相应的右括号)。 - 任何右括号
)必须有相应的左括号(。 - 左括号
(必须在对应的右括号之前)。 *可以被视为单个右括号),或单个左括号(,或一个空字符串。- 一个空字符串也被视为有效字符串。
示例 1:
输入: "()"
输出: True
示例 2:
输入: "(*)"
输出: True
示例 3:
输入: "(*))"
输出: True
注意:
- 字符串大小将在 [1,100] 范围内。
题解
假设没有*号,那么该题就是一个经典的括号序列判断问题,可以使用栈这种数据结构解决。
因为只有一种类型的括号,我们不一定真的使用栈,可以直接使用一个变量 来记录左括号的数量,扫描遇到左括号时 ++,遇到右括号时 --,当过程中出现 或者扫描完整个序列后 说明该括号序列不合法 。
加上*号后,因为*号可以被当做左/右括号或者空字符使用,我们就不能用一个变量来表示左括号的数量,因为数量是不确定的,而是用一个区间表示左括号的数量。
表示左括号数量最小值,表示左括号数量最大值,初始值都为 。
同样的扫描整个序列,
当遇到左括号时,++,++,
当遇到右括号时,--,--,
当遇到 * 时:
- * 取左括号:++,++,
- * 取右括号:--,--,
- * 取空, 不变
- 上面三种情况取交集,--,++
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;
}
};