Leetcode 32:最长有效括号(最详细的解法!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/84173172

给定一个只包含 '('')' 的字符串,找出最长的包含有效括号的子串的长度。

示例 1:

输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"

示例 2:

输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"

解题思路

这种问题我们首先想到的解决思路是通过栈。我们首先遍历一遍s,判断遍历到的字符ch是不是(,如果是的话,我们就将ch.index加入到栈中,例如

( ( )
↑
stack: 0

如果遍历到的元素是),且栈不为空栈顶元素是(,我们就出栈。

( ( )
    ↑
stack: 0

否则如果栈为空,我们就将ch.index入栈。这样扫面完一轮,我们的栈里面存放的就是没有匹配到的位置。例如

stack: | 0 3 7 13 |
      -1         len(s)

此时我们只要遍历stack,找到两两元素之间隔最大的距离即可。

class Solution:
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        s_len, stack = len(s), list()
        for i, ch in enumerate(s):
            if ch == '(':
                stack.append(i)
            elif stack and s[stack[-1]] == '(':
                stack.pop()
            else:
                stack.append(i)

        if not stack:
            return s_len

        stack = [-1] + stack + [s_len]
        for i,val in enumerate(stack[1:]):
            stack[i] = val - stack[i] - 1

        return max(stack[:-1])

这个问题也可以通过动态规划来做,而且思路也非常清晰。我们定义 f ( i ) f(i) 表示当前位置i结尾的最长有效括号的长度,那么

  • f ( i ) = f ( i 1 ) + 2     i f    s [ i 1 f ( i 1 ) ] = = ( f(i)=f(i-1)+2\ \ \ if \ \ s[i-1-f(i-1)]=='('
  • f ( i ) = f ( i ) + f ( i f ( i ) ) f(i)=f(i)+f(i-f(i))

稍微说明一下,因为 f ( i ) f(i) 为此时的最大长度,那么i-1-f(i)就表示之前还未匹配的(,例如

( ) ( ( ) )
    ↑     i

如果我们的i在这个位置,那么i-1-f(i)就是箭头所指的位置。由于此时箭头所指的位置是(,所以我们应该将f(i)+2=4。但是我们此时得到只是一个小区间内的最大值,我们应该还要加上以箭头前一位置结尾的最大长度,那么此时我们得到的解过就是以i结尾的最大长度。

最后这个算法还有一个小问题,如果我们此时i(怎么办?我们上面的f(i)+2就是错误的。所以我们干脆不考虑这种情况,只考虑)即可。那么只考虑)情况是合理的吗?合理,因为最长有效括号一定是以)结尾。

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

reference:

https://leetcode.com/problems/longest-valid-parentheses/discuss/14126/My-O(n)-solution-using-a-stack

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/84173172