678. Valid Parenthesis String
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:
- Any left parenthesis ‘(’ must have a corresponding right parenthesis ‘)’.
- Any right parenthesis ‘)’ must have a corresponding left parenthesis ‘(’.
- Left parenthesis ‘(’ must go before the corresponding right parenthesis ‘)’.
- ‘*’ could be treated as a single right parenthesis ‘)’ or a single left parenthesis ‘(’ or an empty string.
- 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].
题目:判断给定的字符串是否是合法的括号表达式。其中*号可以代表左括弧、右括弧或者任意其他的字符。
思路:贪心算法,参见https://leetcode.com/problems/valid-parenthesis-string/solution/。我们只关心字符串中的括号是否是平衡的,即左括号数目应等于右括号数。但由于*
的存在,使得问题变得麻烦了点。例如给定的字符串是(***)
。对于子串(
,左括弧的个数只有一个;对于字符子串(*
,左括号的数目可以是[0, 1, 2]
三种情况;对于字符子串(**
,左括号的数目可以是[0, 1, 2, 3]
四种情况,(其实还包括-1这种情况,排除);对于字符子串(***
,左括号的数目可以是[0, 1, 2, 3, 4]
五种情况;对于字符子串(***)
,左括号的数目可以是[0, 1, 2, 3]
四种情况,因为在所有的情况中存在左括弧数为0的情况,说明可以组成有效的括号表达式。可以证明,维护的左括号的个数是个连续的数组,因此只需维护数组两侧值。
class Solution {
public:
bool checkValidString(string s) {
int lo = 0, hi = 0;
for(auto c : s){
lo += c == '(' ? 1 : -1;
hi += c != ')' ? 1 : -1;
if(hi < 0) return false;
lo = max(lo, 0);
}
return lo == 0;
}
};