LeetCode678. Valid Parenthesis String
来源:互联网 发布:js防水涂料粘接强度 编辑:程序博客网 时间:2024/06/05 10:53
Analysis
Solution1
The idea is to use an int count
to keep tracking the relationship between left parenthesis and right parenthesis since we don’t care about the exact parenthesis but rather their corresponding counts.
For every character in the input String s
, there are 3 possible conditions:
Current character is
'('
, then we increase thecount
.Current character is
')'
, then we decrease thecount
.Current character is
'*'
, there are 3 possible sub-conditions:- Treat
*
as(
, increasecount
by 1. - Treat
*
as)
, decreasecount
by 1. - Treat
*
as empty string, count does not change.
- Treat
Complexity
The space complexity of this solution is O(1)
without considering the recursion stack. The recursion stack space would be linear to the length of the input String.
The time complexity would be O(n)
as well. Worst case O(2^n)
to O(3^n)
when the input string contains only *
.
Suppose n
is the length of the input string.
Then we have the following solution based on straight-forwardly implement the above thoughts.
class Solution { public boolean checkValidString(String s) { if (s == null || s.isEmpty() || s.length() == 0) { return true; } char[] charS = s.toCharArray(); return checkValidStringHelper(charS, 0, 0); } private boolean checkValidStringHelper(char[] charS, int start, int count) { // Base case if (start == charS.length) { return count == 0 ? true : false; } // If the count smaller than 0, early stop cause this is invalid. if (count < 0) { return false; } if (charS[start] == '(') { return checkValidStringHelper(charS, start + 1, count + 1); } else if (charS[start] == ')') { return checkValidStringHelper(charS, start + 1, count - 1); } else { // charS[start] == '*' // 1. treat '*' as empty string boolean ret1 = checkValidStringHelper(charS, start + 1, count); // 2. treat '*' as left parenthesis boolean ret2 = checkValidStringHelper(charS, start + 1, count + 1); // 3. treat '*' as right parenthesis boolean ret3 = checkValidStringHelper(charS, start + 1, count - 1); return (ret1 || ret2 || ret3); } }}
Solution2 (More optimal)
Another interesting observation is that the resulting count will actually be a continuous sequence of integer.
E.g., for input "(**))"
At step 1, the count would be 1.
At step 2, the count would be 0, 1, or 2
At step 3, the count would be 0+1, 0, 0-1, 1+1, 1, 1-1, 2+1, 2, 2-1
, which is -1, 0, 1, 2, 3
. And since negative count is always invalid, we early stop for these conditions. ==> 0, 1, 2, 3
.
At step 4, the count would be 0, 1, 2
with early pruning.
At step 5, the count would be 0, 1
with early pruning.
Considering that actually the reslut count is a consecutive sequence of integers, we can actually stores only the range of the output rather than iterate through all possible conditions.
Complexity
This algorithm runs in O(1)
space and O(n)
time where n
is the length of the input string.
Resulting to the following solution:
class Solution { public boolean checkValidString(String s) { if (s == null || s.isEmpty() || s.length() == 0) { return true; } int low = 0; int high = 0; for (char c : s.toCharArray()) { if (c == '(') { high++; low++; } else if (c == ')') { if (low > 0) { low--; } high--; } else { //c == '*' if (low > 0) { low--; } high++; } if (high < 0) { return false; } } // Since we have pruned all conditions where low is smaller than 0, the smallest low would be 0 // if the input string is valid. return low == 0; }}
- LeetCode678. Valid Parenthesis String
- 678. Valid Parenthesis String
- 678. Valid Parenthesis String
- [LeetCode]Valid Parenthesis String
- LeetCode-Valid Parenthesis String
- 678. Valid Parenthesis String
- leetcode 678 Valid Parenthesis String
- LWC 50:678. Valid Parenthesis String
- leetcode 678. Valid Parenthesis String 有效括号的判断
- Longest Valid Parenthesis
- LeetCode - Valid Parenthesis
- Leetcode 20 Valid Parenthesis
- 【LeetCode】valid-parenthesis
- Leetcode20-Valid Parenthesis
- Parenthesis
- Parenthesis
- Parenthesis
- LeetCode[String]: Valid Palindrome
- Ubuntu 蓝屏拯救
- Ajax返回xml类型数据
- 词向量源码解析:(6.1)fasttext源码解析
- 数据库-事务
- 代理模式
- LeetCode678. Valid Parenthesis String
- leetcode
- mongodb用户权限管理配置
- 使用jquery处理ajax返回的XML、无刷新技术
- Redis之五种数据类型
- [简单题]Change_it_up Python
- 反射:动态读取XML创建类实例并赋值
- Flask网页出现UnicodeDecodeError
- Android RecyclerView中item焦点乱跳问题(适用于PDA以及TV等带方向键的安卓设备)