题目名称
Valid Parenthesis String
题目描述
Given a string s containing only three types of characters: ‘(’, ‘)’ and ‘*’, return true if s is valid.
The following rules define a valid string:
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 “”.
Example 1:
Input: s = “()”
Output: true
Example 2:
Input: s = “(*)”
Output: true
Example 3:
Input: s = “(*))”
Output: true
Constraints:
1 <= s.length <= 100
s[i] is ‘(’, ‘)’ or ‘*’.
初试思路
1.存在一对括号的左边子串和右边子串即【(左边)右边】都是valid的,则整个字符串也valid,用递归实现。但是会TLE。
2.采用记忆法,空间换时间。因为在计算子串是否是valid时存在重复计算,所以可以将子串是否valid的结果存放在二维数组中。
3. 最佳方案:括号匹配:遇’(‘加一,遇’)'减一,注意处理负数情况。有星号’*‘,count是一个范围,用minCount记录最小count,maxCount记录最大count。
初试代码
// 我的代码1(会TLE)
class Solution {
public:
bool checkValidString(string s) {
return checkValidSubString(s, 0, s.size()-1);
}
bool checkValidSubString(string &s, int i, int j){
if(i>j){
return true;
}
if(s[i] == ')'){
return false;
}
else if(s[i] == '*'){ // '*'当成空
if(checkValidSubString(s, i+1, j)){
return true;
}
}
for(int k=i+1; k<=j; k++){
if(s[k] == ')' || s[k] == '*'){ //’*‘当成’)‘
if(checkValidSubString(s, i+1, k-1) && checkValidSubString(s, k+1, j)){
return true;
}
}
}
return false;
}
};
//我的代码2(空间换时间)
class Solution {
public:
bool checkValidString(string s) {
int **VALID; //0:没算过 1:算过且是true -1:算过且是false
bool res=true;
VALID = new int *[size(s)];
for (int i = 0; i < size(s); i++) {
VALID[i] = new int [size(s)];
}
for(int i=0; i<size(s); i++){
for(int j=0; j<size(s); j++){
VALID[i][j] = 0;
}
}
res = checkValidSubString(s, 0, s.size()-1, VALID);
for (int i = 0; i < size(s); i++) {
delete [] VALID[i];
}
delete []VALID;/*释放数组*/
return res;
}
bool checkValidSubString(string &s, int i, int j, int ** VALID){
if(i>j){
return true;
}
if(VALID[i][j] != 0){//算过了
return VALID[i][j] == 1;
}
if(s[i] == ')'){
VALID[i][j] = -1;
return false;
}
else if(s[i] == '*'){ // '*'当成空
if(checkValidSubString(s, i+1, j, VALID)){
VALID[i][j] = 1;
return true;
}
}
for(int k=i+1; k<=j; k++){
if(s[k] == ')' || s[k] == '*'){
if(checkValidSubString(s, i+1, k-1, VALID) && checkValidSubString(s, k+1, j, VALID)){
VALID[i][j] = 1;
return true;
}
}
}
VALID[i][j] = -1;
return false;
}
};
//代码3(最优版本)
class Solution {
public:
bool checkValidString(string s) {
int minCount = 0;
int maxCount = 0;
for(int i=0; i<size(s); i++){
if(s[i]=='('){
minCount++;
maxCount++;
}
if(s[i]==')'){
minCount--;
maxCount--;
}
if(s[i]=='*'){
minCount--;
maxCount++;
}
if(maxCount<0){
return false;
}
if(minCount<0){
minCount = 0;
}
}
return minCount==0;
}
};
学到了啥
注意二维数组的动态内存分配和释放;
注意分治思想的运用;