您的位置:首页 > 其它

LeetCode 32. Longest Valid Parentheses

2017-09-25 21:52 309 查看
Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.

For “(()”, the longest valid parentheses substring is “()”, which has length = 2.

Another example is “)()())”, where the longest valid parentheses substring is “()()”, which has length = 4.

题目大意:求最长的有效括号子串的长度。

首先是使用stack的解法。

假设括号为(()((),下标一次为0-5。

加入原则(加入的是下标值):

1) 如果栈为空,则入栈,不论是左括号还是右括号。

2)如果栈不为空,且s[i]为右括号,栈顶为左括号,出栈

3)其他情况,直接入栈

以上面的例子,栈的最终状态为 0,3。

45出栈了,说明是个有效子串,

12出栈了,说明是个有效子串。

即栈中,相邻两个下标之间的都是有效子串,求最大即可

代码如下:

class Solution {
public:
int longestValidParentheses(string s) {
int n = s.length();
stack<int> st;
for(int i = 0; i < n; i++) {
if(s[i] == ')' && !st.empty() && s[st.top()] == '(') {st.pop();continue; }
st.push(i);
}
int res = 0;
int a = n , b = 0;
while(!st.empty()) {
b = st.top();
st.pop();
res = max(res,a - b - 1);
a = b;
}
res = max(res, a);
return res;
}
};


栈的解法2: 用一个标记数组,记录每对有效括号,最后求标记数组中最长的连续1的个数。

代码如下:

class Solution {
public:
int longestValidParentheses(string s) {
const int n = s.length();
vector<bool> vis(n,0);
stack<int> st;
for(int i = 0; i < n;  i++) {
if(s[i] == ')' && !st.empty() && s[st.top()] == '(') {
vis[i] = true;
vis[st.top()] =  true;
st.pop();
continue;
}
st.push(i);
}

int res = 0,tmp = 0;
for(int i = 0; i < n; i++) {
if(vis[i] == true) {
tmp++;
}
else {
tmp = 0;
}
res = max(res, tmp);
}
return res;
}
};


动态规划的解法。类似于最大连续子数组和。

假设dp[i]表示以s[i]结尾的最大有效子串的长度。则

if s[i] == ‘(’ , then dp[i] = 0;

else if s[i] == ‘)’ , then

if s[i-1] == ’ (’ , then dp[i] = dp[i-2] + 2;

else if s[i-1] == ‘)’ and s[i - dp[i-1] -1] == ‘(’ , then dp[i] = dp[i] + dp[i-1] + 2 + dp[i-dp[i-1]-2 ];

如果s[i-1]是右括号,我们要查看左边是否有跟s[i]匹配的左括号,那么是哪个括号呢?就是下标为i-dp[i-1]-1的元素。 如果匹配,还要加上i-dp[i-1]-1左边的有效的括号。

代码如下:

int longestValidParentheses(string s) {
if(s.length() <= 1) return 0;
int curMax = 0;
vector<int> longest(s.size(),0);
for(int i=1; i < s.length(); i++){
if(s[i] == ')'){
if(s[i-1] == '('){
longest[i] = (i-2) >= 0 ? (longest[i-2] + 2) : 2;
curMax = max(longest[i],curMax);
}
else{ // if s[i-1] == ')', combine the previous length.
if(i-longest[i-1]-1 >= 0 && s[i-longest[i-1]-1] == '('){
longest[i] = longest[i-1] + 2 + ((i-longest[i-1]-2 >= 0)?longest[i-longest[i-1]-2]:0);
curMax = max(longest[i],curMax);
}
}
}
//else if s[i] == '(', skip it, because longest[i] must be 0
}
return curMax;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息