算法:使用dp
注意:数组直接用dp[1000000]会超过范围应该使用malloc
转载地址
设 d p [ i ] dp[i]dp[i] 表示以 s [ i ] s[i]s[i] 结尾的最长括号匹配长度
显然当 s [ i ] s[i]s[i] 为左括号时 d p [ i ] = 0 dp[i]=0dp[i]=0
当 s [ i ] s[i]s[i] 为右括号时,d p [ i ] dp[i]dp[i] 一定与 d p [ i − 1 ] dp[i-1]dp[i−1] 有关
容易发现 s [ i − d p [ i − 1 ] ] s[i-dp[i-1]]s[i−dp[i−1]] 是 d p [ i − 1 ] dp[i-1]dp[i−1] 的起始字符
则当 s [ i − d p [ i − 1 ] − 1 ] s[i-dp[i-1]-1]s[i−dp[i−1]−1] 与 s [ i ] s[i]s[i] 合法匹配时,有
d p [ i ] = d p [ i − 1 ] + 2 + d p [ i − d p [ i − 1 ] − 2 ] dp[i]=dp[i-1]+2+dp[i-dp[i-1]-2]dp[i]=dp[i−1]+2+dp[i−dp[i−1]−2]
这里的 d p [ i − d p [ i − 1 ] − 2 ] dp[i-dp[i-1]-2]dp[i−dp[i−1]−2] 只需要一个例子就好理解了
123456
1
2
假设此时为 d p [ 5 ] = 2 dp[5]=2dp[5]=2 ,对于以 s [ 5 ] s[5]s[5] 结尾的最长括号匹配显然是[]
然后到了 d p [ 6 ] = 6 dp[6]=6dp[6]=6 ,注意到此时 s [ 3 ] s[3]s[3] 被合法利用了,
这样就造成了 s [ 3 ] s[3]s[3] 之前的 d p [ 6 − d p [ 5 ] − 2 ] = d p [ 2 ] dp[6-dp[5]-2] = dp[2]dp[6−dp[5]−2]=dp[2] 被重新利用
应该很好理解了
————————————————
版权声明:本文为优快云博主「q779」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/qq_50332374/article/details/124792289
#include <iostream>
#include <string>
using namespace std;
int main() {
int Max = 0;
int p = -1;
string ch;
int *dp = (int *)malloc(1000000 * sizeof(int));
getline(cin, ch);
int len = ch.size();
for (int i = 0; i < len; ++i) {
if (ch[i] == '(' || ch[i] == '[') {
dp[i] = 0;
continue;
} else {
if ((ch[i - dp[i - 1] - 1] == '(' && ch[i] == ')' ) || (ch[i - dp[i - 1] - 1] == '[' && ch[i] == ']') ) {
dp[i]
= dp[i - 1] + 2;
if (i >= 2) {
dp[i] += dp[i - dp[i - 1] - 2];
}
if (dp[i] > Max) {
Max = dp[i];
p = i;
}
}
}
}
for (int i = p - dp[p] + 1; i <= p; ++i) {
cout << ch[i];
}
cout << endl;
return 0;
}