###### tags: `Leetcode` `medium` `greedy` `python` `c++` # 678. Valid Parenthesis String ## [題目連結:] https://leetcode.com/problems/valid-parenthesis-string/ ## 題目: Given a string ```s``` containing only three types of characters: ```'('```, ```')'``` and ```'*'```, return ```true``` if ```s``` is **valid**. The following rules define a **valid** string: * 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 ```""```. **Example 1:** ``` Input: s = "()" Output: true ``` **Example 2:** ``` Input: s = "(*)" Output: true ``` **Example 3:** ``` Input: s = "(*))" Output: true ``` ## 解題想法: * 此題為判斷括號字串是否合法: * ' * '可視為左右括號or空字符 * 貪心法: * 遍歷字串,**紀錄當前字符需要')'的數量** * 當前字符為'(': +1 * 當前字符為')': -1 * 因為有萬能' * ',所以需要分別記錄最少與最大值對於')'需要的數量 * 最少需要量minVal: * **將所有' * '都視為')'**,若minVal為0就不用繼續減了,表示目前左右剛剛好or左邊過多,將' * '視為空字符即可 * 最大需要量maxVal: * **將所有' * '都視為'('** * **若為負數,則為False** * 表示即使' * '都轉為左括號,右括號數量仍太多,不滿足合理左右配對 * 最終判斷: * 最小值==0 and 最大值!=負數 * Example: ``` ( ( * * ) * ) min 1 2 1 0 0 0 0 max 1 2 3 4 3 4 3 ``` ## Python: ``` python= class Solution(object): def checkValidString(self, s): """ :type s: str :rtype: bool """ #紀錄當前字符需要的')'數量 #因為有萬能* 所以需要分別記錄最少與最大值 #最少值->將所有*都視為')' :若為0就不用繼續減ㄌ #最大值->將所有*都視為'(' :若為負數 則為False #最終判斷 最小值==0 and 最大值!=負數 minVal=0 maxVal=0 for char in s: if char=='(': minVal+=1 maxVal+=1 elif char==')': if minVal>0: minVal-=1 maxVal-=1 elif char=='*': if minVal>0: minVal-=1 maxVal+=1 print('min:',minVal,'max:',maxVal) if maxVal<0: return False return minVal==0 if __name__=='__main__': result=Solution() s="((**)*)" ans=result.checkValidString(s) print(ans) ``` ## C++: ``` cpp= #include<bits/stdc++.h> using namespace std; class Solution { public: bool checkValidString(string s) { int minNeed=0, maxNeed=0; for (char item: s){ if (item=='('){ minNeed+=1; maxNeed+=1; } else if (item==')'){ if (minNeed>0) minNeed-=1; maxNeed-=1; } else if (item=='*'){ if (minNeed>0) minNeed-=1; //let '*' to be ')' maxNeed+=1; //let '*' to be '(' } if (maxNeed<0) return false; } return minNeed==0; } }; ```