DAY29:leetcode #32 Longest Valid Parentheses

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

For "(()", the longest valid parentheses substring is "()", which has length = 2.

Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

Subscribe to see which companies asked this question

class Solution(object):
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        stack = []
        max_len = 0
        for i in range(len(s)):
            if s[i] == '(':
                stack.append((s[i], i))
            else:
                if len(stack) != 0 and stack[-1][0] == '(':
                    stack.pop()
                    if len(stack) == 0:
                        cur_len = i + 1
                    else:
                        cur_len = i - stack[-1][1]
                    max_len = max(max_len, cur_len)
                else:
                    stack.append((s[i], i))
        return max_len
        

我之前考虑的是不使用栈,仅使用一个数字表示栈中有多少个左括号。但是发现这样子是不行的。原因有这两个:

1、新的右括号进入后,需要上一个没有被消去的左括号的下标,计算这一次括号匹配的长度

2、如果新的右括号没有被左括号消去,那么右括号也需要入栈,作为一个标志,以后的右括号就不能消去这个右括号了。

所以入栈的元素应该是('(', index)这样的一个元组。以上方法可以叫做栈方法

在大神的文章:点击打开链接

里面,还看到了动态规划算法,和不需要额外空间的解法

class Solution(object):
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        dp = [0]*len(s)
        for i in range(1, len(s)):
            if s[i] == ')':
                left = i - dp[i - 1] - 1
                if left >= 0 and s[left] == '(':
                    dp[i] = 2 + dp[i-1]
                    if left > 0:
                        dp[i] += dp[left - 1]
        dp.append(0)        
        return max(dp)

把从后向前的改成从前向后的了

Q:能否不用额外空间求解?A:可以,但是要提高时间复杂度。比如((()()),先遍历一遍将所有的()替换成00,得到((0000),再遍历一遍,替换所有的(00...00)这种形式字符串为000...000,这里我们得到(000000,直到遍历完无法替换更多括号为之。如果所有符号都是0,说明是有效的。这样的时间复杂度是O(N)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值