678. Valid Parenthesis String

288 阅读1分钟

描述

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

解析

根据题意,主要判断字符串是否合法,合法的依据就是左右圆括号能够前后配对,而难点在于 * 可以当作 ( 或者 ) 存在,传统的栈方法不太适合,而观看大神们的解答很巧妙:

遍历 s 中的所有字符 c,利用集合 set 记录当前左括号-右括号的差值
若 c == '(',将 vset 替换为其所有元素 +1c == ')',将 vset 替换为其所有不小于 1 的元素 - 1 ,这里巧妙地解决了类似 ")(" 的情况
若 c == '*’,将 vset 中的所有元素 +1 ,-1 后,保留非负元素
最后看是否在集合中包含 0 ,有 0 则说明字符串中的左右括号和能够替换括号的 * 都能够一一合法配对的情况是存在的

解答

class Solution(object):
	def checkValidString(s):
    old = set([0])
    for c in s:
        new = set()
        if c=="(": 
            for i in old:
                new.add(i+1)
        elif c==")":
            for i in old:
                if i>0:
                    new.add(i-1)
        elif c=="*":
            for i in old:
                new.add(i+1)
                new.add(i)
                if i>0:
                    new.add(i-1)
        old = new
    return 0 in old
    
        	      
		

运行结果

Runtime: 16 ms, faster than 85.10% of Python online submissions for Valid Parenthesis String.
Memory Usage: 12.8 MB, less than 34.38% of Python online submissions for Valid Parenthesis String.

每日格言:人生最大遗憾莫过于错误坚持和轻易放弃