LC.32. 最長有效括號
挺好的一個題,這裏主要再分析一下官方的解法。
思路:
1.。
令以下標結尾的字符串的最大長度爲,顯然,.
當,需要討論兩種情況。
,這樣顯然有.
,因爲我們已知,我們可以找到的開始匹配的前面 一個位置即,顯然如果,是不能更新的,因爲一定是未被匹配的,不然會包含掉它,所以顯然,才能與進行匹配,然後再加上的長度就可以了。
即
時間複雜度:
class Solution {
public:
int longestValidParentheses(string s) {
int n=s.length(),ans=0;
vector<int>dp(n,0);
for(int i=1;i<n;i++){
if(s[i]=='(') dp[i]=0;
else if(s[i-1]=='('){
dp[i]=(i>=2?dp[i-2]:0)+2;
}
else if(i-dp[i-1]>0&&s[i-1-dp[i-1]]=='(')
dp[i]=(i-2-dp[i-1]>=0?dp[i-2-dp[i-1]]:0)+2+dp[i-1];
ans=max(ans,dp[i]);
}
return ans;
}
};
2.棧。
顯然對於這樣的後綴表達式問題,用棧是很方便的。這裏是參考官方大大的解法,預先放一個元素,保證棧底是未被匹配的最後一個右括號下標,如果是左括號直接入棧,否則彈出棧頂元素,如果棧是空的表示不能更新,否則長度爲
時間複雜度:
class Solution {
public:
int longestValidParentheses(string s) {
int n=s.length(),ans=0;
stack<int>sk;sk.push(-1);
for(int i=0;i<n;i++){
if(s[i]=='(') sk.push(i);
else {
sk.pop();
if(sk.empty()) sk.push(i);
else ans=max(ans,i-sk.top());
}
}
return ans;
}
};
3.統計左右括號數。
這種方法我覺得比第二種好理解點,先順序遍歷一遍,如果是左括號,否則,左右括號數相等就更新長度,若,則可以捨棄掉前面所有的括號,。
因爲順序遍歷沒有考慮到的情況,這樣就更新不了。
所以再逆序遍歷一遍,時.這樣就考慮到所有情況了。
時間複雜度:
class Solution {
public:
int longestValidParentheses(string s) {
int n=s.length(),ans=0;
int l=0,r=0;
for(int i=0;i<n;i++){
if(s[i]=='(') l++;
else r++;
if(l==r) ans=max(ans,l*2);
else if(r>l) l=r=0;
}
l=r=0;
for(int i=n-1;i>=0;i--){
s[i]=='('?l++:r++;
if(l==r) ans=max(ans,l*2);
else if(l>r) l=r=0;
}
return ans;
}
};