1. 思路A
一般来说括号这种匹配的一般都是用栈来验证,但是这里如何统计最长有效的括号呢?
下面给出一种方法:
准备栈A和数组B,逐个读入字符串字符c,如果栈顶元素和当前字符c不可以匹配’(’ 和 ‘)’;那么就将当前字符压入栈,并且在数组B中追加一个0;如果可以匹配,那么就将栈顶元素弹出,并且将栈顶对应压入B数组的0改为2。最后统计B数组中连续不为0的数的和即可。
拿"(())(()"举例子:
- 当前字符为 ( ,栈无元素,不能匹配;栈压入(,数组压入0
A : (
B : 0 - 当前字符为 ( ,栈顶为 (,不能匹配;栈压入(,数组压入0
A : ((
B : 0 0 - 当前字符为 ) ,栈顶为 (,可以匹配;栈弹出(,数组对应0改为2
A : (
B : 0 2 - 当前字符为 ) ,栈顶为 (,可以匹配;栈弹出(,数组对应0改为2
A :
B : 2 2 - 当前字符为 ( ,栈无元素,不能匹配;栈压入(,数组压入0
A : (
B : 2 2 0 - 当前字符为 ( ,栈顶为 (,不能匹配;栈压入(,数组压入0
A : ((
B : 2 2 0 0 - 当前字符为 ) ,栈顶为 (,可以匹配;栈弹出(,数组对应0改为2
A : (
B : 2 2 0 2
最后观察,B数组最大连续不为0的和为4,表示最长有效括号为4。
2. 代码A
class Solution {
public:
int longestValidParentheses(string s) {
stack<int> zero;
vector<int> data;
int ret = 0, num = 0;;
for(int i = 0; i < s.length(); ++i)
{
if(zero.empty() || !(s[i] == ')' && data[zero.top()] == -1))
{
zero.push(data.size());
data.push_back(s[i] == '(' ? -1 : -2);
}
else
{
data[zero.top()] = 2;
zero.pop();
}
}
for(int i = 0; i < data.size(); ++i)
{
num = data[i] < 0 ? 0 : num + data[i];
ret = max(num, ret);
}
return ret;
}
};
3. 思路B
因为以前做括号这类题目基本都是用区间dp或者栈,所以先入为主的只想到了方法A,不过在和朋友聊这个题的时候,朋友提供了另一个思路。
1.从左往右找第一个完整括号(),然后向两边扩展直到不能形成更大的有效括号然后记住这个区间[l,r]。
2.然后从区间r右边继续找完整括号(),重复前面1的操作,只不过需要注意,当左边可以跟之前任何一个区间[l,r]的相连接时,就可以连接之前的区间,形成更长的有效括号。
还是拿个字符串举例子"(())(()())"
- 第一个找到的完整括号是[1,2],然后此时向两边扩展到[0,3]。记录一下。
- 从3开始继续找完整括号[5,6],然后扩展到[5,8],继续[4,9],此时已经不能扩展了,但是我们发现[4,9]和前面的[0,3]可以连起来,所以形成了更大的[0,9]。然后也没法继续拓展了,再记录一下。
最后将所有记录过的区间,求长度最长的区间即可。
4. 代码B
class Solution {
public:
int longestValidParentheses(string s) {
stack<int> prel;
stack<int> prer;
int l = 0, r = 0, ret = 0, length = s.length();
while(true)
{
if(r + 1 > length) break;
if(s[r] =='(' && s[r+1] == ')')
{
l = r; r = r + 1;
while(true)
{
if(!prer.empty() && prer.top() == l - 1){
l = prel.top(); prel.pop(); prer.pop();
}
else if(l-2 >= 0 && s[l-2] == '(' && s[l-1] == ')') l -= 2;
else if(r+2 < length && s[r+1] == '(' && s[r+2] == ')') r += 2;
else if(l-1 >= 0 && r+1 < length && s[l-1] == '(' && s[r+1] == ')') l --, r ++;
else break;
}
ret = max(ret, r - l + 1);
prel.push(l);prer.push(r);
}
r ++;
}
return ret;
}
};
本文探讨了两种解决最长有效括号问题的算法思路。思路A利用栈和数组记录括号匹配过程,通过统计连续非零值求得最长有效括号长度。思路B则采用区间扩展方法,从左至右寻找并扩展有效括号区间,实现高效求解。
4077

被折叠的 条评论
为什么被折叠?



