括号字符串的最长有效长度

括号字符串的最长有效长度

题目描述

给定一个括号字符串str,返回最长的能够完全正确匹配括号字符字串的长度。

输入描述:

输出一行字符串,代表 s t r ( 1 ≤ l e n g t h s t r ≤ 1 0 5 ) str(1 \leq length_{str} \leq 10^5) str(1lengthstr105)

输出描述:

输出一个整数,代表括号字符串的最长有效长度。

示例1
输入
(()())
输出
6
示例2
输入
())
输出
2
备注:

时间复杂度 O ( n ) O(n) O(n),额外空间复杂度 O ( n ) O(n) O(n)


题解:

一维动态规划,F[i] 表示 str[0…i] 以字符 str[i] 结尾的最长有效括号子串长度,分以下几种情况:

  • 若 str[i] == ‘(’,则 F[i] = 0,因为有效括号字符串必定以 ‘(’ 结尾;
  • 若 str[i] == ‘)’,则以 str[i] 结尾的最长有效括号子串可能存在,F[i-1] 代表以 str[i-1] 结尾的最长有效括号子串的长度,若 str[i-F[i-1]-1] 为 ‘(’ ,就能与 str[i] 配对有效括号,即 F[i] = F[i-1] + 2。但是,我们的 F[i] 表示的是以 str[i] 结尾的 最长有效括号子串长度 ,所以我们应该把前面的部分也加上,即 F[i] += F[i-F[i-1]-2],然后记录最大的 F[i] 即可。
代码:
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 100001;

char s[N];
int f[N];

int main(void) {
    
    
    scanf("%s", s);
    int i, t, ret = 0;
    for (i = 1; s[i]; ++i) {
    
    
        if (s[i] == '(') continue;
        t = i - f[i - 1] - 1;
        if (t >= 0 && s[t] == '(') {
    
    
            f[i] = f[i - 1] + 2;
            if (t > 0)
                f[i] += f[t - 1];
        }
        if (f[i] > ret) ret = f[i];
    }
    printf("%d\n", ret);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/MIC10086/article/details/108907968
今日推荐