# 有效的括号字符串 给定一个只包含三种字符的字符串:`(`、`)`和`*`,写一个函数来检验这个字符串是否为有效字符串,有效字符串具有如下规则: * 任何左括号`(`必须有相应的右括号`)`。 * 任何右括号`)`必须有相应的左括号`(`。 * 左括号`(`必须在对应的右括号之前`)`。 * `*`可以被视为单个右括号`)`,或单个左括号`(`,或一个空字符串。 * 一个空字符串也被视为有效字符串。 ## 示例 ``` 输入: "()" 输出: True ``` ``` 输入: "(*)" 输出: True ``` ``` 输入: "(*))" 输出: True ``` ## 题解 ```javascript /** * @param {string} s * @return {boolean} */ var checkValidString = function(s) { var n = s.length; var lSeq = 0; for(let i=0;i=0;--i){ if(s[i] !== "(") ++rSeq; else --rSeq; if(rSeq < 0) return false; } return true; }; ``` ## 思路 采用双向遍历的方式,两种极端边界假设,首先假设所有`*`都为`(`,因左括号必须在配对的左边,故从左向右遍历,看是否足够覆盖所有`)`,然后假设假设所有`*`都为`)`,因右括号必须在配对的右边,故从右向左遍历,看是否足够覆盖所有`(`,如果双向都能够成立,那么就能够满足题目要求条件。具体实现是采用两个计量变量`lSeq`与`rSeq`,正向扫描时遇到非`)`时就自增计量变量,否则就自减计量变量,如果计量值负值,那么说明不符合匹配条件,直接返回`false`,若一次遍历正好完全匹配,则直接返回`true`,剪枝不再进行逆向遍历,在进行逆向遍历时同理,当逆向扫描到非`(`时就自增计量变量,否则就自减计量变量,如果计量值负值,那么说明不符合匹配条件,直接返回`false`,两次遍历都正常完成则返回`true`。 ## 每日一题 ``` https://github.com/WindrunnerMax/EveryDay ``` ## 参考 ``` https://leetcode-cn.com/problems/valid-parenthesis-string ```