给定一个字符串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; } }