leetcode 32. Longest Valid Parentheses(python)

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

描述

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

Example 1:

Input: s = "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()".
复制代码

Example 2:

Input: s = ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()".
复制代码

Example 3:

Input: s = ""
Output: 0
复制代码

Note:

0 <= s.length <= 3 * 10^4
s[i] is '(', or ')'.
复制代码

解析

根据题意,给定一个仅包含字符 '(' 和 ')' 的字符串,找出最长有效的括号子字符串的长度。

这道题的题目很简单,我们一看到这种括号类型的题目,基本上解决方法也就确定了,那就是用栈,因为左右括号的配对,我们是用栈顶元素和新来的元素就能进行很好的判断,决定括号该保留还是该出栈。

这里我们要找的是合法字符串的最长长度,按照常规思路,我们要计算长度,肯定要知道左边界和右边界,右边界肯定是新来的括号,左边界就需要我们保存在栈里面,左边界其实就是我们已经遍历过的左括号的索引,所以:

  • 遇到左括号的时候,我们就将其索引入栈
  • 遇到右括号的时候,有两种情况:第一种情况是如果栈不为空,说明当前右括号有可以配对的左括号,我们用此时的右括号索引减去栈顶的左括号索引,就是当前合法子字符串的长度,同时更新结果值;第二种情况就是栈为空,说明当前右括号没有可以配对的左括号,直接将其索引入栈,表示已经遍历过的字符在这个位置不合法,也就是当前最后一个没有成功匹配的右括号索引。

时间复杂度为 O(N) ,空间复杂度为 O(N) 。

解答

class Solution(object):
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        result = 0
        stack = [-1]
        for i, c in enumerate(s):
            if c == '(':
                stack.append(i)
            elif c == ')':
                stack.pop()
                if not stack:
                    stack.append(i)
                else:
                    result = max(result, i-stack[-1])
        return result
		
复制代码

运行结果

Runtime: 49 ms, faster than 42.05% of Python online submissions for Longest Valid Parentheses.
Memory Usage: 14.3 MB, less than 38.15% of Python online submissions for Longest Valid Parentheses.
复制代码

解析

当然因为这道题是求“最值”类型的题目,我们也可以用动态规划来尝试解决,定义 dp[i] 表示索引为 i 的字符位结尾时候出现的最长合法括号子字符串的长度。

  • 当 s[i] = '(' 的时候,我们知道肯定 dp[i] 为 0 ,因为当前位置还无法形成合法的括号组合

  • 当 s[i] = ')' 的时候,我们有两种情况需要讨论:

  • (一)当 s[i-1] 为 '(' 的时候,我们知道此时的 s[i-1] 和 s[i] 可以形成合法的括号此时 dp[i] 最少为 2 ,但是在 s[i-1] 之前也有可能有相邻的合法的子字符串,也可有可能不是,这都无所谓,我们只需要加上即可,此时的

      dp[i] = dp[i-2] + 2 
    复制代码
  • (二)当 s[i-1] 为 ')' 的时候,我们知道此时的 i-dp[i-1]-1 到 i-1 的范围内是合法的子字符串,同时 i-dp[i-1]-1 之前的以 i-dp[i-1]-2 位结尾的子字符串也可能有合法的子字符串,所以

      dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2]
    复制代码

时间复杂度为 O(N) ,空间复杂度为 O(N) 。

解答

class Solution(object):
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        N = len(s)
        dp = [0] * N
        result = 0
        for i in range(1, N):
            c = s[i]
            if c == ')':
                if s[i - 1] == '(':
                    dp[i] = 2
                    if i >= 2:
                        dp[i] = dp[i - 2] + dp[i]
                elif dp[i - 1] > 0:
                    if i - dp[i - 1] - 1 >= 0 and s[i - dp[i - 1] - 1] == '(':
                        dp[i] = dp[i - 1] + 2
                        if i - dp[i - 1] - 2 >= 0:
                            dp[i] = dp[i] + dp[i - dp[i - 1] - 2]
            result = max(result, dp[i])
        return result
复制代码

运行结果

Runtime: 52 ms, faster than 36.85% of Python online submissions for Longest Valid Parentheses.
Memory Usage: 14.2 MB, less than 38.15% of Python online submissions for Longest Valid Parentheses.
复制代码

原题链接

leetcode.com/problems/lo…

您的支持是我最大的动力

猜你喜欢

转载自juejin.im/post/7102218913135460389