题目 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:
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.
An empty string is also valid.
测试例子
Example 1
Input: “()”
Output: True
Example 2
Input: “(*)”
Output: True
Example 3
Input: “(*))”
Output: True
代码
版本一(没通过)
只是简单通过栈来匹配左右括号
#include<iostream>
#include<stack>
#include<string>
using namespace std;
class Solution {
public:
bool checkValidString(string s) {
if(s.empty()) return true;
stack<char> cs;
int cx = 0;//count ‘*’ number
for(int i=0;i<s.size();++i){
if(s[i]=='(') cs.push('(');
else if(s[i]=='*') ++cx;
else{
if(!cs.empty()){
cs.pop();
}else if(cx){
cx--;
}else{
return false;
}
}
}
if(cs.empty()||cx>=cs.size()) return true;
else return false;
}
};
上面的代码只是简单考虑左右括号的匹配,却没有考虑*的位置问题。如下用例即测出错误
Input: “(())((())()()()(()(())())())()()((()())((()))(*”
Output: true
Expected: false
这个用例通过上述程序可以看成如下字符串,可以看出为什么错误了:
“**(“
版本二(AC)
仔细考虑版本一的流程发现,版本一一定会把右括号后所有处理完,即右括号后面还有则会将其统计而查看是否有左括号消除。这样一来,我们上面碰到的问题可以通过重右向左再便利一次匹配来消除。即有版本二代码。
#include<iostream>
#include<stack>
#include<string>
using namespace std;
class Solution {
public:
bool checkValidString(string s) {
if(s.empty()) return true;
return checkValidString1(s)&&checkValidString2(s);
}
bool checkValidString1(string& s) {
stack<char> cs;
int cx = 0;//count star char number
for(int i=0;i<s.size();++i){
if(s[i]=='(') cs.push('(');
else if(s[i]=='*') ++cx;
else{
if(!cs.empty()){
cs.pop();
}else if(cx){
cx--;
}else{
return false;
}
}
}
if(cs.empty()||cx>=cs.size()) return true;
else return false;
}
bool checkValidString2(string& s) {
stack<char> cs;
int cx = 0;//count star char number
for(int i=s.size()-1;i>=0;--i){
if(s[i]==')') cs.push(')');
else if(s[i]=='*') ++cx;
else{
if(!cs.empty()){
cs.pop();
}else if(cx){
cx--;
}else{
return false;
}
}
}
if(cs.empty()||cx>=cs.size()) return true;
else return false;
}
};
一键传送大神代码
class Solution {
public:
bool checkValidString(string s) {
int lower = 0, upper = 0;
for (char c : s) {
if (c=='(') {
lower++;
upper++;
} else if (c==')') {
lower--;
upper--;
} else { // * encountered
lower--;
upper++;
}
lower = max(lower, 0);
if (upper<0) // unmatched ')' found in the middle of string
return false;
}
return lower==0;
}
};