1刷
题目很简单,一开始总是想是dp,区间dp,后来发现dp在合并和顺序的时候有问题。看题结竟然还是stack!!!思路要方向,只想到如何求ok的,没想到从没ok的反推ok的!
用两个栈保存,一个保存“()”,一个保存索引,两个栈的操作相同。最后未出栈的元素就是无法匹配的元素,同时也是各个有效括号组的分界点,据此由各个索引相减求最大值即可。
class Solution {
public:
int longestValidParentheses(string s) {
stack<char>st;
stack<int>n;
int maxx = 0;
int num;
for(int i = 0; i < s.length(); ++ i){
if(st.empty()){
st.push(s[i]);
n.push(i);
}
else if(s[i] == '('){
st.push('(');
n.push(i);
}
else{
if(st.top() == '('){
st.pop();
n.pop();
}
else{
st.push(')');
n.push(i);
}
}
}
int last = s.length();
int t;
while(!n.empty()){
t = n.top();
if(last - t - 1 > maxx) maxx = last - t - 1;
last = t;
n.pop();
}
if(last > maxx) maxx = last;
return maxx;
}
};
2刷
2刷用了1刷的方法,的确是好方法,要用还在stack上面的留下来的标记(一开始还是用了除去的,这样不行的,这个是逆向思维)
先放上2刷的dp代码
If s[i] is ‘(‘, set longest[i] to 0,because any string end with ‘(’ cannot be a valid one.
Else if s[i] is ‘)’
If s[i-1] is '(', longest[i] = longest[i-2] + 2
Else if s[i-1] is ')' and s[i-longest[i-1]-1] == '(', longest[i] = longest[i-1] + 2 + longest[i-longest[i-1]-2]
其实很好想的dp,难点在于dp表示什么意思这个比较难,dp i是包括i的从开始到i最长的长度!!!!想到dp表达形式应该比较容易想出dp方程
class Solution {
public:
int longestValidParentheses(string s) {
if(s.length() <= 1) return 0;
int maxx = 0;
vector<int>dp(s.length(), 0);
for(int i = 1; i < s.length(); ++ i){
if(s[i] == ')'){
if(s[i - 1] == '('){
dp[i] = (i - 2) >= 0 ? dp[i - 2] + 2 : 2;
maxx = maxx > dp[i] ? maxx : dp[i];
}
else{
if(i - dp[i - 1] - 1 >= 0 && s[i - dp[i - 1] - 1] == '('){
dp[i] = dp[i - 1] + 2 + (i - dp[i - 1] - 2 >= 0 ? dp[i - dp[i - 1] - 2] : 0);
maxx = maxx > dp[i] ? maxx : dp[i];
}
}
}
return maxx;
}
};
这是1刷的
class Solution {
public:
int longestValidParentheses(string s) {
stack<int>num;
stack<char>c;
int maxx = 0;
num.push(0);
for(int i = 0; i < s.length(); ++ i){
if(c.empty() || s[i] == '('){
num.push(i + 1);
c.push(s[i]);
continue;
}
char ds = c.top();
if(ds == '('){
c.pop();
num.pop();
}
else{
num.push(i + 1);
c.push(s[i]);
}
}
int t = s.length() + 1;
while(!num.empty()){
maxx = maxx > t - num.top() - 1 ? maxx : t - num.top() - 1;
t = num.top();
num.pop();
}
return maxx;
}
};