您的位置:首页 > 其它

LeetCode Longest Valid Parentheses 括号匹配

2015-12-06 20:51 211 查看
括号匹配问题一般的处理方式有两种:①使用栈的push/pop模拟;②给括号赋予正负的分值(+1/-1),从左到右计算分数之和。一个合法的串中任意位置的分数不会小于0(左括号数大于等于右括号)。
题意:给定一个由“(”和")"组成的字符串,求最长合法子串的长度。
栈一般用来判定括号序列是否合法,这里使用第二种方法。从左到右扫描一遍,遇到分数小于0则跳过该位置,从下一个位置起继续向右扫描,遇到分数为0的位置时则更新结果,处理代码如下:

int l = 0, r = 0, sum = 0;
int ans1 = 0;
while(r < len){
sum += s[r] == '(' ? 1 : -1;
if(sum < 0){
l = r + 1;
sum = 0;
}
else if(sum == 0){
if(r - l + 1 > ans1)
ans1 = r - l + 1;
}
++r;
}

但我们仅仅只能排除掉不合法的位置,获得“局部最优解”,最后剩下的串中左括号的数目可能大于右括号(最容易想到的情况是:起点处左括号刚好冗余),所以最优解可能包含在剩下的串中未进行更新。这种情况怎么处理呢?换个方向想一想,从左到右扫描,左括号的数目大于等于右括号;反过来,从右到左扫描,右括号的数目大于等于左括号,否则序列非法。所以对于剩下的串,只需从右往左扫描一次,就可以找出包含在其中的合法序列。
设从左到右扫描时,最后的待定串为

,则定有:

中任意位置处的分数都大于0,否则该位置要么被跳过、要么被更新。设

中最后一个')'的位置为

,则对所有

。则从右往左扫描时,这些

都会被跳过,然后从

开始进行计算,对其他位置同理。这是因为,从左到右

中任意位置的左括号大于右括号数,而这在从右往左扫描时,是非法的,这些非法的位置会被跳过,而合法的位置则会被更新。所以最后能得到正确的结果。代码如下:

class Solution {
public:
int longestValidParentheses(string s) {
int len = s.size(), i = 0, j = len - 1;
int l = 0, r = 0, sum = 0;
int ans = 0;
while(r < len){
sum += s[r] == '(' ? 1 : -1;
if(sum < 0){
l = r + 1;
sum = 0;
}
else if(sum == 0){
if(r - l + 1 > ans)
ans = r - l + 1;
}
++r;
}
int bound = l;
r = len - 1, l = len - 1, sum = 0;
int tmp = 0;
while(l > bound){
sum += s[l] == '(' ? 1 : -1;
if(sum > 0){
r = l - 1;
sum = 0;
}
else if(sum == 0){
if(r - l + 1 > tmp)
tmp = r - l + 1;
}
--l;
}
return ans > tmp ? ans : tmp;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: