给定一个字符串s,字符串s只包含以下三种字符: (,*,),请你判断 s是不是一个合法的括号字符串。合法括号字符串有如下规则:
1.左括号'('必须有对应的右括号')'
2.右括号')'必须有对应的左括号'('
3.左括号必须在对应的右括号前面
4.*可以视为单个左括号,也可以视为单个右括号,或者视为一个空字符
5.空字符串也视为合法的括号字符串
数据范围:
"()()"
true
"((*)"
true
"(*)"
true
"(((*)"
false
import java.util.*;
/**
* NC175 合法的括号字符串
* @author d3y1
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @return bool布尔型
*/
public boolean isValidString (String s) {
return solution1(s);
// return solution2(s);
// return solution3(s);
}
/**
* 栈
* @param s
* @return
*/
private boolean solution1(String s){
Stack<Integer> leftStack = new Stack<>();
Stack<Integer> starStack = new Stack<>();
char ch;
for(int i=0; i<s.length(); i++){
ch = s.charAt(i);
if(ch == '('){
leftStack.push(i);
}
else if(ch == '*'){
starStack.push(i);
}
else if(ch == ')'){
if(!leftStack.isEmpty()){
leftStack.pop();
}else if(!starStack.isEmpty()){
starStack.pop();
}else{
return false;
}
}
}
while(!leftStack.isEmpty()){
if(!starStack.isEmpty() && leftStack.peek()<starStack.peek()){
leftStack.pop();
starStack.pop();
}else{
return false;
}
}
return true;
}
/**
* 贪心
* @param s
* @return
*/
private boolean solution2(String s){
// 待消除左括号的最小个数
int minLeft = 0;
// 待消除左括号的最大个数
int maxLeft = 0;
for(char ch: s.toCharArray()){
if(ch == '('){
minLeft++;
maxLeft++;
}
else if(ch == '*'){
// * -> )
if(minLeft > 0){
minLeft--;
}
// * -> (
maxLeft++;
}
else if(ch == ')'){
if(minLeft > 0){
minLeft--;
}
// 已经没有'('或'*'与当前')'匹配
if(maxLeft == 0){
return false;
}
maxLeft--;
}
}
return minLeft==0;
}
/**
* 动态规划
*
* dp[i][j]表示子串s[i,j]是否为合法的括号字符串
*
* len=1:
* dp[i][i] = true , s.charAt(i) == '*'
*
* len=2:
* dp[i][i+1] = true , (currCh=='('||currCh=='*') && (nextCh==')'||nextCh=='*')
*
* len>=3:
* dp[i][j] = dp[i+1][j-1] , (leftCh=='('||leftCh=='*') && (rightCh==')'||rightCh=='*')
* dp[i][j] = dp[i][k]&&dp[k+1][j] , i<=k<j&&!dp[i][j]
*
* @param s
* @return
*/
private boolean solution3(String s){
int n = s.length();
boolean[][] dp = new boolean[n][n];
// len=1 -> *
for(int i=0; i<n; i++){
if(s.charAt(i) == '*'){
dp[i][i] = true;
}
}
// len=2 -> () (* *) **
char currCh,nextCh;
for(int i=0; i+1<n; i++){
currCh = s.charAt(i);
nextCh = s.charAt(i+1);
if((currCh=='('||currCh=='*') && (nextCh==')'||nextCh=='*')){
dp[i][i+1] = true;
}
}
// len>=3
char leftCh,rightCh;
for(int i=n-3; i>=0; i--){
for(int j=i+2; j<n; j++){
leftCh = s.charAt(i);
rightCh = s.charAt(j);
// (())
if((leftCh=='('||leftCh=='*') && (rightCh==')'||rightCh=='*')){
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];
// }
for(int k=i; k<j; k++){
if(dp[i][j]){
break;
}
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 isValidString (String s) {
if (s.length() == 0) {
return true;
}
LinkedList<Integer> leftStack = new LinkedList<>();
LinkedList<Integer> starStack = new LinkedList<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '(') {
leftStack.push(i);
} else if (ch == '*') {
starStack.push(i);
} else if (ch == ')') {
if (!leftStack.isEmpty()) {
leftStack.pop();
} else if (!starStack.isEmpty()) {
starStack.pop();
} else {
return false;
}
}
}
while (!leftStack.isEmpty() && !starStack.isEmpty()) {
if (leftStack.peek() > starStack.peek()) {
return false;
}
leftStack.pop();
starStack.pop();
}
return leftStack.isEmpty();
}
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param s string字符串
* @return bool布尔型
*/
public boolean isValidString (String s) {
Stack<Integer> left = new Stack<>();
Stack<Integer> start = new Stack<>();
for(int i=0;i<s.length();i++){
//左括号或者*号分别入栈
if(s.charAt(i) == '('){
left.push(i);
}
if(s.charAt(i) == '*'){
start.push(i);
}
//如果是右括号,先从左括号栈中匹配,不满足再从*栈中匹配。
//匹配:栈不为空,且栈的元素比当前下标小。
if(s.charAt(i) == ')'){
if(!left.isEmpty() && left.peek()<i){
left.pop();
}else{
if(!start.isEmpty() && start.peek()<i){
start.pop();
}else{
return false;
}
}
}
}
//再判断左括号的栈是否为空,用*进行匹配。
while(!left.isEmpty() && !start.isEmpty()){
if(left.peek() < start.peek()){
left.pop();
start.pop();
}else{
return false;
}
}
//如果左括号的栈为空,则合格;否则不合格。
if(left.isEmpty()){
return true;
}else{
return false;
}
}
}
public boolean isValidString (String s) {
int m=0,n=0;
for(int i=0;i<s.length();i++){
if(s.charAt(i)==')')m--;
else m++;
if(s.charAt(s.length()-1-i)=='(')n--;
else n++;
if(m<0||n<0)return false;
}
return true;
} public boolean isValidString (String s) {
Deque<Integer> de1=new LinkedList<>();
Deque<Integer> de2=new LinkedList<>();
for(int i=0;i<s.length();i++) {
char c=s.charAt(i);
if(c=='(')
de1.push(i);
else if(c=='*')
de2.push(i);
else {
if(de1.size()>0) {
de1.pop();
}else if(de2.size()>0) {
de2.pop();
}else {
return false;
}
}
}
if(de1.size()>de2.size())
return false;
while(de1.size()>0) {
if(de1.pop()>de2.pop())
return false;
}
return true;
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @return bool布尔型
*/
public boolean isValidString (String s) {
// write code here
int left = 0, right = 0, star = 0;
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
if(c == '('){
left ++;
}else if(c == ')'){
right ++;
}else{
star ++;
}
if(left + star < right) return false;
}
left = 0;
right = 0;
star = 0;
for(int i = s.length() - 1; i >= 0; i--){
char c = s.charAt(i);
if(c == '('){
left ++;
}else if(c == ')'){
right ++;
}else{
star ++;
}
if(right + star < left) return false;
}
return true;
}
}