Longest Valid Parentheses解题心得
题目来源:https://leetcode.com/problems/longest-valid-parentheses/description/
my code:https://github.com/zhanzongyuan/leetcode/blob/master/032_Longest%20Valid%20Parentheses.cpp
题目描述
输入仅包含
'(',')'
的字符串s
,定义有效括弧子串为括弧左右两两对应,一个左括弧对应一个右括弧,可以嵌套;求s的最长有效括弧子串长度
maxLen
解题思路
Stack 解题
- 思维误区(自己脑袋的坑!!!):
- 将stack定义为操作单元为
char
的数据类型,如stack<char>
,同时希望通过记录在pop操作过程的次数来更新最长长度,结果是各种bug层出不断 - 正确的解决方法应该是通过
stack<int>
实现,其中存储的是压入栈的下标
- 将stack定义为操作单元为
- 正确解决思路:
- 对每个字符
s[i]
,如果s[i]=='('
则将下标i
压入stack - 如果字符
s[i]==')'
,则查看栈顶的下标对应的元素是否为'('
,如果是则弹出栈顶元素,反之压入')'
对应下标i
- 最后处理完
s
后得到的stack中剩下的是相邻的valid parentheses
的分隔符的下标位置,由此可以算得最长的valid paretheses
- 对每个字符
- 代码实现
//stack
int longestValidParentheses1(string s) {
stack<int> invalidPos;
invalidPos.push(-1);
int maxLen=0;
for (int i=0; i<s.size(); i++){
if (s[i]=='(') {
int len=i-invalidPos.top()-1;
maxLen=maxLen<len?len:maxLen;
invalidPos.push(i);
}
else if (s[i]==')'){
if (!invalidPos.empty()&&s[invalidPos.top()]=='(') invalidPos.pop();
else {
int len=i-invalidPos.top()-1;
maxLen=maxLen<len?len:maxLen;
invalidPos.push(i);
}
}
}
int len=s.size()-invalidPos.top()-1;
maxLen=maxLen<len?len:maxLen;
return maxLen;
}
DP 动态规划解题
思维误区(自己脑袋的坑!!!)
一开始思考的动态转移方程式这样的:
f(x,y)=( f(x+1,y-1) & s[x]=='(' & s[y]==')' ) | ( f(x+2,y) & s[x]=='(' & s[x+1]==')' ) | ( f(x,y-2) & x[y-1]=='(' & x[y]==')' )
其中f(x,y)代表:
s在[x,y]的闭区间上的子串是否有效
,f(x,y)的类型是boolean- 但是后来发现该状态转移方程不完备(看来还是自己的动态规划算法的状态转移方程的运用和实现不熟悉,得多做几道总结才行)
正确解题方法:
- f(x)代表:以
s
中下标为x
的字符为结尾,可以得到的最长有效子串,即该有效子串是以当前s[x]
结尾的最长子串 通过形如
"(...)((...))"
的子串形式的分析得到:longestLen[i]+=2+longestLen[i-1]+longestLen[i-(2+longestLen[i-1])]; //in fact: //take it as (...)((..)) if (i-1>=0&&i-1-longestLen[i-1]>=0&&s[i-1-longestLen[i-1]]=='('){ longestLen[i]+=2+longestLen[i-1]; if (i-longestLen[i]>=0) longestLen[i]+=longestLen[i-longestLen[i]]; }
具体为什么这样就需要思考对
“()”
和“()(())”
的情况的考虑,同时思考错误不匹配的情况- 代码实现:
//DP int longestValidParentheses2(string s) { int maxLen=0; int n=s.size(); vector<int> longestLen(n, 0); for (int i=0; i<n; i++){ if (s[i]==')'){ //take it as (...)((..)) if (i-1>=0&&i-1-longestLen[i-1]>=0&&s[i-1-longestLen[i-1]]=='('){ longestLen[i]+=2+longestLen[i-1]; if (i-longestLen[i]>=0) longestLen[i]+=longestLen[i-longestLen[i]]; } } if (maxLen<longestLen[i]) maxLen=longestLen[i]; } return maxLen; }
- f(x)代表:以