LeetCode 678. Valid Parenthesis String
原题链接在这里:https://leetcode.com/problems/valid-parenthesis-string/description/
题目:
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].
题解:
Accumlate count of parenthesis and star.
When encountering *, increment starCount.
When encountering (, first make sure there is no more starCount than parCount.
If yes, these many more * could affect final decision. like ***(((. Finally, starCount >= parCount, but should return false.
Make starCount = parCount. Then increment parCount.
When encountering ), before decrementing parCount, if both parCount and starCount are 0, that means too many ), return false.
Finally, check if starCount >= parCount. These startCount happens after (, and they could be treated as ).
Time Complexity: O(s.length()).
Space: O(1).
AC Java:
1 class Solution { 2 public boolean checkValidString(String s) { 3 if(s == null || s.length() == 0){ 4 return true; 5 } 6 7 int parCount = 0; 8 int starCount = 0; 9 for(int i = 0; i<s.length(); i++){ 10 char c = s.charAt(i); 11 if(c == '('){ 12 if(starCount > parCount){ 13 starCount = parCount; 14 } 15 16 parCount++; 17 }else if(c == '*'){ 18 starCount++; 19 }else{ 20 if(parCount == 0){ 21 if(starCount == 0){ 22 return false; 23 } 24 25 starCount--; 26 }else{ 27 parCount--; 28 } 29 } 30 } 31 32 return starCount >= parCount; 33 } 34 }
When encountering ( or ), it is simple to increment or decrement.
遇到"*". 可能分别对应"(", ")"和empty string 三种情况. 所以计数可能加一, 减一或者不变. 可以记录一个范围[lo, hi].
lo is decremented by * or ).
hi is incremented by * or (.
When hi < 0, that means there are too many ), return false.
If lo > 0 at the end, it means there are too many ( left, return false.
Since lo is decremented by * and ), it could be negative. Thus lo-- should only happen when lo > 0 and maintain lo >= 0.
lo = Math.max(lo, 0). If lo is negative, which means there are * who is treated as ) while it should be treated as "".
Note: lo can't be smaller than 0. When hi < 0, return false.
Time Complexity: O(s.length()).
Space: O(1).
AC Java:
1 class Solution { 2 public boolean checkValidString(String s) { 3 if(s == null || s.length() == 0){ 4 return true; 5 } 6 7 int lo = 0; 8 int hi = 0; 9 for(int i = 0; i<s.length(); i++){ 10 if(s.charAt(i) == '('){ 11 lo++; 12 hi++; 13 }else if(s.charAt(i) == ')'){ 14 lo--; 15 hi--; 16 }else{ 17 lo--; 18 hi++; 19 } 20 21 if(hi < 0){ 22 return false; 23 } 24 lo = Math.max(lo, 0); 25 } 26 27 return lo == 0; 28 } 29 }