zoukankan      html  css  js  c++  java
  • [LeetCode] 32 Longest Valid Parentheses (栈 or DP)

    题意:

    给你一个括号序列,求其中最长的合法括号序列的长度。

    思路:

    这个题的核心思路,其实是合法括号序列的定义。

    合法括号的定义如下:

    1. "()" 是一个合法括号序列;
    2. 如果 "|" 表示一个合法序列,那么 "(|)" 也是一个合法序列;
    3. 如果 "|" 表示一个合法序列,那么 "||" 也是一个合法序列。

    一个简单思路是,枚举所有序列,然后判断这个序列是否是合法序列。判断方法是:对于一个序列,可以根据定义递归判断是否符合上面三条之一。如果用记忆化搜索,最多需要计算 O(N^2) 次判断过程,然后枚举也是 O(N^2) 次。所以这种思路的整体时间复杂度是 O(N^2)。但是这个题 O(N^2) 会 TLE。

    根据括号匹配栈的特性,可以维护每一段合法括号的长度,最后找最大的一段合法括号序列。

    根据定义,我们可以按下面方式来求出一个合法括号序列:

    1. 定义一个栈,来维护括号序列;
    2. 如果遇到 "(" 则直接入栈;
    3. 如果遇到 ")":
      1. 如果栈顶是 "(",则 "(" 出栈,入栈 "()" 的合法序列;
      2. 如果栈顶两个元素形如 "(" + "|",则出栈这两个元素,入栈 "(|)";
      3. 合并栈顶的连续合法序列
    class Solution:
        def longestValidParentheses(self, s: str) -> int:
            if not s:
                return 0
    
            stack = []
            for c in s:
                if '(' == c:
                    stack.append(1)
                else:
                    top = 0
                    while stack and stack[-1] % 2 == 0:
                        top += stack.pop()
                    if stack and stack[-1] == 1:
                        stack.pop()
                        top += 2
                        stack.append(top)
                    else:
                        if top:
                            stack.append(top)
                        stack.append(-1)
            rlt = 0
            cur = 0
            for i in stack:
                if i % 2 == 1:
                    cur = 0
                else:
                    cur += i
                rlt = max(rlt, cur)
            return rlt
    

    DP

    dp 思路如下: 用 dp[i] 表示结尾为第 i 字符的最长合法序列的长度。根据定义可以得到以下递推关系:

    1. 若第 i 个字符是 "(",则 dp[i] = 0;
    2. 若第 i 个字符是 ")",则:
      1. 若第 i-1 个字符是 "(" 则 dp[i] 为 "()" 的长度加它前面一段的最长合法长度(定义3);
      2. 若 dp[i-1] > 0 (前面是一个合法序列),则许要看这个序列前一个字符是不是 "("。(定义2)
    class Solution:
        def longestValidParentheses(self, s: str) -> int:
            if not s: return 0
            
            dp = [0 for _ in s]
            for idx, c in enumerate(s):
                if ')' == c:
                    if idx > 0 and s[idx-1] == '(':
                        dp[idx] = (dp[idx-2] if idx > 1 else 0) + 2
                        continue
                    if (dp[idx-1] > 0) and (idx > dp[idx-1]) and (s[idx-dp[idx-1]-1] == '('):
                        dp[idx] = dp[idx-1] + 2
                        if idx-dp[idx-1]-1 > 0:
                            dp[idx] += dp[idx-dp[idx-1]-2]
            return max(dp)
    
  • 相关阅读:
    Cortex-M3 在C中上报入栈的寄存器和各fault状态寄存器
    Cortex-M3 双堆栈指针(MSP&PSP)
    Cortex-M3 异常返回值EXC_RETURN
    Cortex-M3 异常中断响应与返回
    Cortex-M3 操作模式与特权等级
    Cortex-M3 R0~R15寄存器组 & 特殊功能寄存器组
    【Python】批量修改指定目录下所有文件的文件名/后缀
    【EMV L2】EMV终端数据
    【EMV L2】Cardholder Verification Rule(CVR) Format
    【EMV L2】GPO响应以及AIP、AFL
  • 原文地址:https://www.cnblogs.com/Phantom01/p/13548790.html
Copyright © 2011-2022 走看看