给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
- 任何左括号 ( 必须有相应的右括号 )。
- 任何右括号 ) 必须有相应的左括号 ( 。
- 左括号 ( 必须在对应的右括号之前 )。
- * 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
- 一个空字符串也被视为有效字符串。
"()"
true
"(*)"
true
"(*))"
true
字符串大小将在 [1,100] 范围内。
class Solution {
public:
/**
*
* @param s string字符串
* @return bool布尔型
*/
bool checkValidString(string s) {
// write code here
int l=0,r=0;
for(int i=0;i<s.length();i++){
l+=s[i]==')'?-1:1;
r+=s[s.length()-1-i]=='('?-1:1;
if(l<0||r<0)
return false;
}
return true;
}
}; import java.util.*;
public class Solution {
/**
*
* @param s string字符串
* @return bool布尔型
*/
public boolean checkValidString(String s) {
// write code here
Stack<Integer> stars = new Stack<>();
Stack<Integer> stack = new Stack<>();
char[] chs = s.toCharArray();
for(int i = 0;i<chs.length;i++) {
char ch = chs[i];
if (ch == '(') {
stack.push(i);
} else if (ch == '*') {
stars.push(i);
} else if (ch == ')') {
if (stack.isEmpty() && stars.isEmpty()) {
return false;
} else if (!stack.isEmpty()) {
stack.pop();
} else if (!stars.isEmpty()) {
stars.pop();
}
}
}
if (stack.size() > stars.size()) {
return false;
} else {
while(!stack.isEmpty() && !stars.isEmpty()) {
int x = stack.pop();
int y = stars.pop();
if (y < x) {
return false;
}
}
return stars.size() >= 0;
}
}
} class Solution {
public:
/**
*
* @param s string字符串
* @return bool布尔型
*/
bool checkValidString(string str) {
deque<int> lp,k;
for(int i=0;i<str.size();i++){
if(str[i]=='(') lp.push_back(i);//'('的个数
if(str[i]=='*') k.push_back(i);//'*'的个数
if(str[i]==')') {
if(lp.empty()&&k.empty()){
return false;
}else if(!lp.empty()){
lp.pop_back();
}else if(!k.empty()){
k.pop_front();
}
}
}
if(k.size()<lp.size()){
return false;
}
while(!lp.empty()){
//cout<<k.front()<<" "<<lp.front()<<endl;
while(!k.empty()&&lp.front()>k.front()) k.pop_front();
if(lp.size()>k.size()) return false;
k.pop_front();lp.pop_front();
}
return true;
}
};
这道题关键部分是‘*’字符,它可以转变任意字符,因此先考虑"()"括号匹配成功的情况,最后再考虑剩余的'*',还有剩余的‘(’或者‘)’,左括号或右括号最终只能剩余一种或者都没有。因此利用deque容器存储各个字符的位置,为了后面判断剩余的字符是否符合匹配原则,比如剩余"***(((",很明显'*'字符优先于'(',这种情况也不会匹配成功。首先声明两个deque容器,lp,k分别存储'('和'*'字符的所在字符串中的位置,然后枚举每次插入,若找到一个')',这时候就开始匹配,优先考虑lp存储的左括号,而且是最近的那个左括号,即为lp末端的,然后再考虑k容器的'*'。至于为什么要优先考虑'*'的最前面的元素,是为了最后只剩余'('左括号进行比较,让'*'尽可能在'('的右边,这样才能匹配成功。字符串枚举完成后,然后对lp和k容器进行比较,只需要比较它们出现先后顺序与剩余元素的个数即可。
class Solution:
def checkValidString(self , s ):
# write code here
stack = []
stars = []
for i, c in enumerate(s):
if c == '(':
stack.append(i)
elif c == '*':
stars.append(i)
elif c == ')':
# 先用星号和左括号去平衡右括号
if not stack and not stars:
return False
elif stack:
stack.pop()
elif stars:
stars.pop()
# 剩下的星号只能当右括号或者空
if len(stack) > len(stars):
return False # 此时剩下的左括号无法被星号平衡完
else:
while stack and stars:
i, j = stack.pop(), stars.pop()
# 此时星号要中和掉左括号的话其位置必须在左括号右边
if i > j:
return False
# 星号可以为空,允许没有中和完
return len(stars) >= 0 import java.util.*;
public class Solution {
/**
*
* @param s string字符串
* @return bool布尔型
*/
public boolean checkValidString (String s) {
int n =s.length();
boolean [][]dp=new boolean[n][n];
//basecase
for (int i = 0; i < n; i++) {
if (s.charAt(i)=='*'){
dp[i][i]=true;
}
}
for (int i = 0; i < n-1; i++) {
if ((s.charAt(i)=='('||s.charAt(i)=='*')&&(s.charAt(i+1)=='*'||s.charAt(i+1)==')')){
dp[i][i+1]=true;
}
}
for (int i = n-3; i >=0; i--) {
for (int j = i+2; j < n; j++) {
char l=s.charAt(i);
char r=s.charAt(j);
if( (l=='*'||l=='(')&&(r=='*'||r==')') ){
dp[i][j]=dp[i+1][j-1];
}
for (int k = i; k < j&&!dp[i][j]; k++) {
dp[i][j]=dp[i][k]&&dp[k+1][j];
}
}
}
return dp[0][n-1];
}
} import java.util.*;
public class Solution {
/**
*
* @param s string字符串
* @return bool布尔型
*/
public boolean checkValidString (String s) {
char[] cs = s.toCharArray();
int n = cs.length;
int[] left = new int[n], star = new int[n];
int li = -1, si = -1;
for (int i = 0; i < n; i++) {
if (cs[i] == '(') {
left[++li] = i;
} else if (cs[i] == '*') {
star[++si] = i;
} else {
if (li >= 0) {
li--;
} else if (si >= 0) {
si--;
} else {
return false;
}
}
}
while (li >= 0) {
if (si < 0 || star[si] < left[si]) {
return false;
}
si--;
li--;
}
return true;
}
} import java.util.*;
public class Solution {
/**
*
* @param s string字符串
* @return bool布尔型
*/
public boolean checkValidString (String s) {
if(s.length() == 0) return true;
Queue q1 = new LinkedList();
Queue q2 = new LinkedList();
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) == '(') q1.offer(i);
else if(s.charAt(i) == '*') q2.offer(i);
else {
if(!q1.isEmpty()) q1.poll(); // 只要左右括号对等,那么用哪个 `(` 匹配(包括 `*` 转化的)都是可以的
else if(!q2.isEmpty()) q2.poll(); // 删除最前面的 `*`,增大 `*` 匹配 `(` 可能性
else return false; // 没有可匹配的 `(`
}
}
while(!q1.isEmpty()) {
while(!q2.isEmpty() && q2.peek() < q1.peek()) { // 最左边 `*` 位置若不在 `(` 右边
q2.poll();
}
if(q2.isEmpty()) return false;
q1.poll(); // `*` 当作右括号,匹配上啦
}
return true;
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
System.out.println(new Main().checkValidString(str));
}
/**
*
* @param s string字符串
* @return bool布尔型
*/
// 暴力替换
public boolean checkValidString (String s) {
if (s == null || s.length() == 0) {
return true;
}
char[] chars = s.toCharArray();
return dfs(chars, 0, chars.length - 1);
}
// bug 的原因 每次减1, 都要判断一次
int stackCount = 0;
boolean dfs (char[] chars, int start, int end) {
if (start > end) {
return stackCount == 0;
}
char ch = chars[start];
int tmp;
if (ch == '(') {
stackCount++;
return dfs(chars, start + 1, end);
}
if (ch == ')') {
stackCount--;
if (stackCount < 0) {
return false;
}
return dfs(chars, start + 1, end);
}
tmp = stackCount;
// 当作(
stackCount++;
boolean result = dfs(chars, start + 1, end);
if (result) { // 匹配,不再向下
return true;
}
// 否则,回說
stackCount = tmp;
// 当作)
stackCount--;
if (stackCount < 0) {
return false;
}
result = dfs(chars, start + 1, end);
if (result) {
return true;
}
stackCount = tmp;
// 当作*
result = dfs(chars, start + 1, end);
if (result) {
return true;
}
return false;
}
} #
#
# @param s string字符串
# @return bool布尔型
#
class Solution:
def checkValidString(self , s ):
# write code here
n = len(s)
dp = [[False] * n for _ in range(n)]
for i in range(n):
if s[i] == '*':
dp[i][i] = True
# x - i + 1= length
for length in range(2, n + 1):
for i in range(n):
if i + length - 1 <= n - 1:
if length == 2:
if s[i] in ['(', '*'] and s[i + 1] in [')', '*']:
dp[i][i + 1] = True
else:
if s[i] in ['(', '*'] and s[i + length - 1] in [')', '*'] and dp[i + 1][i + length - 2]:
dp[i][i + length - 1] = True
for k in range(i, i + length - 1):
dp[i][i + length - 1] = (dp[i][k]&dp[k + 1][i + length - 1])|dp[i][i + length - 1]
return dp[0][n - 1]
sol = Solution()
print(sol.checkValidString("(*)")) class Solution:
def checkValidString(self , s ):
res=[]
for i in s:
if i=='('&nbs***bsp;i=='*':
res.append(i)
else:
j=1
while j<=len(res) and res[-j]!='(':
j+=1
if j<=len(res):
del res[-j]
elif len(res)!=0:
res.pop()
elif len(res)==0:
return False
r=[]#stack for *
i=0
for i in range(len(res)-1,-1,-1):
if res[i]=="*":
r.append(res[i])
else:
if len(r)>0 and r[-1]=="*":
r.pop()
else:
return False
if '(' not in r:
return True import java.util.*;
public class Solution {
/**
*
* @param s string字符串
* @return bool布尔型
*/
public boolean checkValidString (String s) {
// write code here
if (s == null || s.length() == 0) {
return true;
}
char[] sc = s.toCharArray();
int n = sc.length;
int left = 0, right = 0;
for (int i = 0; i < n; ++i) {
//从左向右
left += sc[i] == ')' ? -1 : 1;
//从右向左
right += sc[n - 1 - i] == '(' ? -1 : 1;
if (left < 0 || right < 0)
return false;
}
return true;
}
} class Solution {
public:
bool checkValidString(string str) {
stack<int> left, s;
for (int i = 0; i < str.size(); ++i) {
if (str[i] == '(') {
left.push(i);
} else if (str[i] == '*') {
s.push(i);
} else {
if (!left.empty()) {
left.pop();
} else if (!s.empty()) {
s.pop();
} else {
return false;
}
}
}
while (!left.empty() && !s.empty()) {
if(left.top() > s.top()) {
return false;
}
left.pop();
s.pop();
}
return left.empty();
}
}; 变成’(‘从左往右匹配’)‘再变成’)‘从右往左匹配’(‘
int left = 0;
int right = 0;
for(int i=0;i<s.length();i++){
if(s[i]=='('||s[i]=='*') left++;
else left--;
if(left<0) return false;
}
for(int i=s.length()-1;i>=0;i--){
if(s[i]==')'||s[i]=='*') right++;
else right--;
if(right<0) return false;
}
return true; function checkValidString( s ) {
const arrStack = []
for (let i = 0; i < s.length; i++) {
let anyVal = s[i]
if (anyVal === "*") arrStack.push("*")
if (anyVal === "(") arrStack.push("(")
if (anyVal === ")") {
if (arrStack.length === 0) return false
let numStarIndex = -1
for (let j = arrStack.length - 1; j > -1; j--) {
if (arrStack[j] === "(") {
arrStack.splice(j, 1)
break
}
if (arrStack[j] === "*" && numStarIndex === -1) numStarIndex = j
}
if (numStarIndex !== -1) arrStack.splice(numStarIndex, 1)
}
}
let numTmp = Math.floor(arrStack.length / 2)
for (let i = 0; i < numTmp; i++) {
let anyLeft = arrStack[i]
let anyRight = arrStack[arrStack.length - i - 1]
if (anyLeft === "(" && anyRight === "*") {
arrStack[i] = "*"
}
if (anyLeft === "*" && anyRight !== ")") {
arrStack[arrStack.length - i - 1] = "*"
}
}
if (arrStack.length !== 0) {
return !(arrStack.indexOf("(") !== -1 || arrStack.indexOf(")") !== -1);
}
return true
}