[LeetCode] 678. Valid Parenthesis String 验证括号字符串
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].
判断给定的字符串的括号匹配是否合法, 20. Valid Parentheses 的变形,这题里只有小括号'()'和*,*号可以代表'(', ')'或者相当于没有。
解法1: 迭代
解法2: 递归,最容易想到的解法,用一个变量cnt记录左括号的数量,当遇到*号时分为三种情况递归下去。Python TLE, C++: 1148 ms
解法2: 最优解法,设两个变量cmin和cmax,cmin最少左括号的情况,cmax表示最多左括号的情况,其它情况在[cmin, cmax]之间。遍历字符串,遇到左括号时,cmin和cmax都自增1;当遇到右括号时,当cmin大于0时,cmin才自减1,否则保持为0(因为其它*情况可能会平衡掉),而cmax减1;当遇到星号时,当cmin大于0时,cmin才自减1(当作右括号),而cmax自增1(当作左括号)。如果cmax小于0,说明到此字符时前面的右括号太多,有*也无法平衡掉,返回false。当循环结束后,返回cmin是否为0。
Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 ; } |
Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Solution( object ): def checkValidString( self , s): """ :type s: str :rtype: bool """ lower, upper = 0 , 0 # keep lower bound and upper bound of '(' counts for c in s: lower + = 1 if c = = '(' else - 1 upper - = 1 if c = = ')' else - 1 if upper < 0 : break lower = max (lower, 0 ) return lower = = 0 # range of '(' count is valid |
Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def checkValidString( self , s): cmin = cmax = 0 for i in s: if i = = '(' : cmax + = 1 cmin + = 1 if i = = ')' : cmax - = 1 cmin = max (cmin - 1 , 0 ) if i = = '*' : cmax + = 1 cmin = max (cmin - 1 , 0 ) if cmax < 0 : return False return cmin = = 0 |
Python:
1 2 3 4 5 6 7 | def checkValidString( self , s): cmin = cmax = 0 for i in s: cmax = cmax - 1 if i = = ')' else cmax + 1 cmin = cmin + 1 if i = = '(' else max (cmin - 1 , 0 ) if cmax < 0 : return False return cmin = = 0 |
Python: TLE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | class Solution( object ): def checkValidString( self , s): """ :type s: str :rtype: bool """ return self .helper(s, 0 ) def helper( self , s, count): # if not s: # return count == 0 if count < 0 : return False for i in xrange ( len (s)): if s[i] = = '(' : count + = 1 elif s[i] = = ')' : if count < = 0 : return False else : count - = 1 else : return self .helper(s[i + 1 :], count + 1 ) or \ self .helper(s[i + 1 :], count) or \ self .helper(s[i + 1 :], count - 1 ) return count = = 0 if __name__ = = '__main__' : print Solution().checkValidString( "(((((*(()((((*((**(((()()*)()()()*((((**)())*)*)))))))(())(()))())((*()()(((()((()*(())*(()**)()(())" ) |
C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class Solution { public : bool checkValidString(string s) { stack< int > left, star; for ( int i = 0; i < s.size(); ++i) { if (s[i] == '*' ) star.push(i); else if (s[i] == '(' ) left.push(i); else { if (left.empty() && star.empty()) return false ; if (!left.empty()) left.pop(); else star.pop(); } } while (!left.empty() && !star.empty()) { if (left.top() > star.top()) return false ; left.pop(); star.pop(); } return left.empty(); } }; |
C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class Solution { public : bool checkValidString(string s) { return helper(s, 0, 0); } bool helper(string s, int start, int cnt) { if (cnt < 0) return false ; for ( int i = start; i < s.size(); ++i) { if (s[i] == '(' ) { ++cnt; } else if (s[i] == ')' ) { if (cnt <= 0) return false ; --cnt; } else { return helper(s, i + 1, cnt) || helper(s, i + 1, cnt + 1) || helper(s, i + 1, cnt - 1); } } return cnt == 0; } }; |
C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Solution { public : bool checkValidString(string s) { int low = 0, high = 0; for ( char c : s) { if (c == '(' ) { ++low; ++high; } else if (c == ')' ) { if (low > 0) --low; --high; } else { if (low > 0) --low; ++high; } if (high < 0) return false ; } return low == 0; } }; |
类似题目:
[LeetCode] 20. Valid Parentheses 合法括号
All LeetCode Questions List 题目汇总
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步