[LeetCode]Longest Valid Parentheses 最长有效括号数

Longest Valid Parentheses 最长有效括号数

动态规划

思路:看到这道题,首先想到的是动态规划,然后想用之前做最长回文串的思路来做,但是后来发现它的括号并不一定是嵌套的,比如()(),这种情况下用之前的方法就不行了。

假定dp[i]表示从下标i开始到字符串最后构成的最长回文串的长度,这样的话需要从后面往前面扫,保证最后得到的值是最值。状态转移方程为:

end = i + 1 + dp[i+1]
1. dp[i] = dp[i+1] + 2  (if s[i] == '(' and s[end]== ')')
2. dp[i] += dp[end+1] (if end+1<len(s))

end表示从i开始,然后经历dp[i+1]记录下的最长串长度,然后加上1;该位置如果为右括号说明当前和之前的是相对应的,所以加上2;还需要注意的是,在end之后可能还有独立的括号区间,比如()(),所以还需要加上后面的可能的长度。

class Solution(object):
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        n = len(s)
        dp = [0] * n
        res = 0
        for i in range(n-2, -1, -1):
            if s[i] == '(':
                right = i + 1 + dp[i+1]
                if right < n and s[right] == ')':
                    dp[i] = dp[i+1] + 2
                    # 后面可能还有独立的括号
                    if right < n-1:
                        dp[i] += dp[right+1]
            res = max(res, dp[i])
        return res

思路:这种括号的应该也可以想到使用栈来做,既然是要记录长度,我们就用栈来记录下标,如果遇到左括号,则加入到栈中,如果遇见右括号,在当前栈中没有的值的时候,表明这个右括号是无效的,则将起始位置设置成当前右括号的位置的下一位,如果栈存在的话,又分为两种情况:一种是弹出以后,栈中还有值,说明仅仅是匹配了独立的一部分,比如((()));另外一种是全部匹配完了,栈中没有值了,那么我们就计算从开始到现在的长度,比如()()()

class Solution(object):
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        start = 0
        stack = []
        res = 0
        for i in range(len(s)):
            if s[i] == '(':
                stack.append(i)
            else:
                if stack:
                    stack.pop()
                    # 表明仅仅匹配完一个区间的括号,还有剩余的括号
                    if stack:
                        res = max(i - stack[-1], res)
                    else: # 表明从start到i都是匹配的
                        res = max(i - start + 1, res)
                else:
                    start = i + 1  # 过滤掉没用的)
        return res
posted @ 2017-09-16 16:00  banananana  阅读(460)  评论(0编辑  收藏  举报