题目链接:
https://www.luogu.com.cn/problem/P1944
题目大意:
给一个只包含‘(’,‘)’,‘[’,‘]’的非空字符串,“()”和“[]”是匹配的,寻找字符串中最长的括号匹配的子串,若有两串长度相同,输出靠前的一串。
思路:
设给定的字符串为 s ,可以定义数组 dp[i], dp[i] 表示以 s[i] 结尾的字符串里最长的括号匹配的字符。
显然,从 i - dp[i] + 1 到 i 的字符串是括号匹配的,当找到一个字符是‘)’或‘]’时,再去判断第 i - 1 - dp[i - 1] 的字符和第 i 位的字符是否匹配,如果是,那么 dp[i] = dp[i - 1] + 2 + dp[i - 2 - dp[i - 1]]
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
string s;
int len, dp[maxn], ans, id;
int main(){
cin >> s;
len = s.length();
for (int i = 1; i < len; i++){
if ((s[i] == ')' && s[i - 1 - dp[i - 1]] == '(' ) || (s[i] == ']' && s[i - 1 - dp[i - 1]] == '[')){
dp[i] = dp[i - 1] + 2 + dp[i - 2 - dp[i - 1]];
if (dp[i] > ans) {
ans = dp[i]; //记录长度
id = i; //记录位置
}
}
}
for (int i = id - ans + 1; i <= id; i++)
cout << s[i];
cout << "\n";
return 0;
}