给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
- 任何左括号 ( 必须有相应的右括号 )。
- 任何右括号 ) 必须有相应的左括号 ( 。
- 左括号 ( 必须在对应的右括号之前 )。
- * 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
- 一个空字符串也被视为有效字符串。
"()"
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 }