32. Longest Valid Parentheses 最长有效括号

题目链接

tag:

  • Hard;
  • Dynamic Programming;

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

Example 1:

Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"

Example 2:

Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"

思路:

1. 栈解法:
需要利用一个变量start来记录有效子串的起始下标,res表示答案。
遍历所有字符

  • 如果当前字符s[index]为'(',将index入栈
  • 否则判断栈是否为空:
    • 如果为空,则说明这个右括号无效,不影响结果,start = index + 1
    • 如果不为空,则出栈,即找到一个左括号和它匹配
      • 如果栈空,则说明从start到index的匹配完了,res = max(res, index - start + 1)
      • 如果栈不为空,则res = max(res, index - s[栈顶]),即栈顶+ 1 ~~ index都匹配了
class Solution {
public:
    int longestValidParentheses(string s) {
        int res=0, start=0;
        stack m;
        for(int i=0; i

2. DP解法:
一般对于最长XX问题容易想到利用DP求解,在这题中利用逆向DP,设状态dp[i]为从i到len - 1中,以i开头的最长合法子串长度:

  • 初始化:dp[len - 1] = 0
  • 如果s[i] = ')',则跳过,因为不可能有由'('开头的串
  • 如果s[i] = '(',则需要找到右括号和它匹配,可以跳过以i + 1开头的合法子串,则需要看j = i + dp[i + 1] + 1是否为右括号。如果没越界且为右括号,那么有dp[i] = dp[i + 1] + 2,此外在这个基础上还要将j + 1开头的子串加进来(只要不越界)
class Solution {
public:
    int longestValidParentheses(string s) {
        if (s.empty()) return 0;
        vector dp(s.size(), 0);
        int res = 0;
        for (int i=s.size()-2; i>=0; --i) {
            if (s[i] == '(') {
                int j = i + dp[i+1] + 1;
                if (s[j] == ')' && j < s.size()) {
                    dp[i] = dp[i+1] + 2;
                    if (j+1 < s.size())
                        dp[i] += dp[j+1];
                }
                res = max(res, dp[i]);
            }
        }
        return res;
    }
};

你可能感兴趣的:(32. Longest Valid Parentheses 最长有效括号)