最长的括号子串
OJ 地址:最长的括号子串
方法一:暴力破解
括号要是有效的,必定是成对出现的。比如一个长度为 7 的字符串,我们可以先以 6 个字符为窗口进行滑动判断,如果 6 个字符没有匹配的,再以 4 个字符为窗口进行滑动判断。
但是要超时。
bool isMatch(string str)
{
stack<char> s;
for(int i = 0; i < str.size(); i++)
{
if(str[i] == '(')
s.push(str[i]);
else
{
if(s.empty())
return false;
else
{
if(s.top() == '(')
{
s.pop();
}
}
}
}
if(s.empty())
return true;
return false;
}
int longestValidParentheses(string s) {
// write code here
int len = s.size();
int sz;
if(len % 2 == 0)
sz = len;
else
sz = len - 1;
for(;sz >= 2; sz -= 2)
{
int l = 0, r = l + sz - 1;
while(r < s.size())
{
if(isMatch(s.substr(l, sz)))
{
return sz;
}
else
{
l++;
r++;
}
}
}
}
方法二:动态规划
我们定义 dp[i] 表示以下标 i 字符结尾的最长有效括号的长度。我们将 dp 数组全部初始化为 0。显然有效的子串一定是以 ‘)’ 结尾,因此我们可以知道以 ‘(’ 结尾的子串对应的 dp 值必定为 0。我们只需要求解出数组中对应的值。
class Solution {
public:
/**
*
* @param s string字符串
* @return int整型
*/
int longestValidParentheses(string s) {
// write code here
vector<int> dp(s.size(), 0);
int maxValue = 0;
for(int i = 0; i < s.size(); i++)
{
if(s[i] == ')')
{
int pre = i - dp[i-1] - 1;
if(pre >= 0 && s[pre] == '(')
{
dp[i] = dp[i-1] + 2;
if(pre - 1 >= 0)
{
dp[i] += dp[pre-1];
}
}
}
maxValue = max(maxValue, dp[i]);
}
return max(maxValue, 0);
}
};