678. Valid Parenthesis String

678. Valid Parenthesis Stringarrow-up-right

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:

  1. Any left parenthesis '(' must have a corresponding right parenthesis ')'.

  2. Any right parenthesis ')' must have a corresponding left parenthesis '('.

  3. Left parenthesis '(' must go before the corresponding right parenthesis ')'.

  4. '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string.

  5. 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].

My Solutions:

星号可以作为左括号、右括号、empty string。那么星号什么时候都能当括号来用吗,来看两个例子:

  • *): 星号可以当左括号来用

  • *(: 论星号当左括号,右括号,还是空,*( 都是不对的

因此,不能发生星号在(的前面,同时(的后面没有)的情况。只要星号在右括号前面,就一定可以消掉右括号。所以当遇到右括号时,就算此时之前没有左括号在stack里,只要之前有*出现过,就可以用*来当左括号使用。

方法1:用一个char stack只记录左括号,用一个counter记录*的数量

  • 碰到左括号:push进去左括号。

  • 碰到右括号:

    • 如果stack里还有左括号,pop出来

    • 如果stack里没有了,但是*的counter>0, counter--,因为*可以当做左括号使用

    • 不然直接返回false

  • 碰到*:

    • 先检查stack里有没有左括号,如果有,就先pop左括号出来,*的counter++。当做把这个stack里一个左括号用*替代的右括号取消掉。

    • 无论如何,再次counter++,因为当前这个*可以将来作为左括号使用。

最后检查stack是不是为空。

方法2:优化上面的方法,不需要stack来记录左括号,只要一个int 数来记录。

方法3:用two pointer的方法。

  • 一个int left记录从左边开始,遇到*和左括号就+1,遇到右括号就-1,代表从左开始,*和左括号的数量大于右括号的数量

  • 一个int right记录从右边开始,遇到*和右括号就+1,遇到左括号就-1,代表从右开始,*和右括号的数量大于左括号的数量

  • 在for loop的每一次循环之中检查left和right有没有小于0的值,如果有,说明把星号替代成括号也消除不了相对应的括号,return false

Last updated