题目描述
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].
思路
- 动态规划:O (n^3) [i][j]范围是否合法,可以从[i-1][j-1] [i][j-1] [i-1][j-1] 推出。还有可能是从某个点 k ,[i][k] [k+1][j] 两个得到的。
- 栈:左括号栈和右括号栈,遇见左括号或者星号,入栈。遇见右括号,用左括号抵消或者星号抵消。最后用星号抵消左括号,条件是星号在左括号右边。时间复杂度:O (n)
代码
代码一:
class Solution {
public:
bool check(char a, char b) {
if ((a == '(' && b == '*') || (a == '*' && b == ')') || (a == '*' && b == '*') || (a == '(' && b == ')'))
return true;
return false;
}
bool checkValidString(string s) {
if (s.empty()) return true;
int n = s.length();
vector<vector<int> > dp(n, vector<int>(n, 0));
for (int l=1; l<=n; ++l) {
for (int i=0, j=i+l-1; j<n; ++i, ++j) {
if (l == 1) {
if (s[i] == '*')
dp[i][j] = 1;
}
else if (j == i+1) {
if (check(s[i], s[j])) dp[i][j] = 1;
}
else {
if ((dp[i+1][j-1] && check(s[i], s[j])) || (dp[i][j-1] && s[j] == '*') || (dp[i+1][j] && s[i] == '*'))
dp[i][j] = 1;
}
for (int k=i; k<j; ++k) {
dp[i][j] |= (dp[i][k] && dp[k+1][j]);
}
}
}
return dp[0][n-1];
}
};
代码二:
class Solution {
public:
bool checkValidString(string s) {
stack<int> left;
stack<int> star;
int n = s.length();
for (int i=0; i<n; ++i) {
if (s[i] == '(') left.push(i);
else if (s[i] == '*') star.push(i);
else {
if (!left.empty()) left.pop();
else if (!star.empty()) star.pop();
else return false;
}
}
while(!left.empty() && !star.empty()) {
if (star.top() < left.top()) return false;
left.pop();
star.pop();
}
return left.empty();
}
};