题目:
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
方法1:贪心
采用left,right两个计数器。
从右向左遍历,如果左括号比右括号多则计数器置0,右括号与左括号相等时记录长度,与最大长度比较。
那如果右括号一直比左括号多呢?
从左向右再遍历一次啦!
代码:
#include<iostream>
#include<stack>
using namespace std;
int main()
{
string a;
cin>>a;
stack<char> s;
int len = a.size();
int max = 0;
int right = 0;
int left = 0;
int t = 0;
for(int i = len - 1; i >= 0; i--){
a[i] == '(' ? left++ : right++;
if(left == right)
{
if(t > max) max = t + 1;
}
if(right < left)
{
left = right = 0;
t = -1;
}
t++;
}
left = right = t = 0;
for(int i = 0; i < len; i++)
{
a[i] == '(' ? left++ : right++;
if(left == right)
{
if(t > max) max = t + 1;
}
if(right > left)
{
left = right = 0;
t = -1;
}
t++;
}
cout<<max;
}
方法二:动态规划
思路:用dp[n]记录以位置n结尾的最长有效子串。
若a[n]=’(’, 则dp[n]=0;
若a[n]=’)’,则:
-
a[n-1]=’(’,则dp[n]=dp[n-1]+2;
-
a[n-1]=’)’,则找到与a[n-1]匹配的括号,
看他的前一个字符(即n-1-dp[n-1]):如果是')',则dp[n]=0; 如果是'(',则dp[n]=dp[n-2-dp[n-1]]+dp[n-1]+2. (还要看n-1-dp[n-1]的前一个位置的子串,因为可以连起来)
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
int main()
{
string a;
cin>>a;
int dp[1000];
dp[0] = 0;
for(int i = 1; i < a.size(); i++)
{
if(a[i] == '(')
{
dp[i] = 0;
}
else
{
if(a[i-1] == '(')
{
if(i - 2 >= 0)
dp[i] = dp[i-2] + 2;
else
dp[i] = 2;
}
else
{
if(a[i-1-dp[i-1]] == ')')
dp[i] = 0;
else
{
if(i-2-dp[i-1] < 0)
dp[i] = dp[i-1] + 2;
else
dp[i] = dp[i-1] + dp[i-2-dp[i-1]] + 2;
}
}
}
}
int max = 0;
for(int i = 0; i < a.size(); i++)
{
if(dp[i] > max) max = dp[i];
}
cout<<max;
}