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].
思路:自己想的办法比较烦,类似于维持一个左括号的计数,该值不能小于0
package l678;
class Solution {
public boolean checkValidString(String s) {
int left = 0, star4left = 0, star = 0, setPoint = 0;
char[] cs = s.toCharArray();
for(int i=0; i<cs.length; i++) {
char c = cs[i];
if(c == '(') left++;
else if(c=='*')star++;
else if(c==')')left--;
// 少left,就从*号里面取出一个来表示,而且这些星号还不能表示成')'
if(left == -1) {
star4left += star; // 不能表示右括号了
if(star4left == 0) return false;
left = 0;
star4left --;
star = 0;
setPoint = i+1;
} else if(left == 0) {
star4left += star; // 不能表示右括号了
star = 0;
setPoint = i+1;
}
}
if(left == 0) return true;
// 如果右括号有多,还要再遍历一遍
int t = 0, starUseCnt = 0;
for(int i=setPoint; i<cs.length; i++) {
if(cs[i] == '(') t++;
else if(cs[i]==')')t--;
else if(t>0) {
t--;
starUseCnt ++; // 先把*认为是),记录这样替换的次数
}
if(t == -1) {
if(starUseCnt == 0) return false;
starUseCnt--; // 之前*可能替换成),替换过头了,判断下
t = 0;
}
}
return t <= 0;
}
}
有人是:维护左括号的lower bound 和 upper bound
the idea is to similar to the solution of without '*'. keep a lower bound of '(' counts and an upper bound of '(' count.
public boolean checkValidString(String s) {
int low = 0;
int high = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
low++;
high++;
} else if (s.charAt(i) == ')') {
if (low > 0) {
low--;
}
high--;
} else {
if (low > 0) {
low--;
}
high++;
}
if (high < 0) {
return false;
}
}
return low == 0;
}
也有很naive的递归
How to check valid parenthesis w/ only ( and )? Easy. Count each char from left to right. When we see (, count++; when we see ) count--; if count < 0, it is invalid () is more than (); At last, count should == 0.
This problem added *. The easiest way is to try 3 possible ways when we see it. Return true if one of them is valid.
class Solution {
public boolean checkValidString(String s) {
return check(s, 0, 0);
}
private boolean check(String s, int start, int count) {
if (count < 0) return false;
for (int i = start; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(') {
count++;
}
else if (c == ')') {
if (count <= 0) return false;
count--;
}
else if (c == '*') {
return check(s, i + 1, count + 1) || check(s, i + 1, count - 1) || check(s, i + 1, count);
}
}
return count == 0;
}
}