given a string containing just the
characters <code>‘(‘</code> and <code>‘)‘</code>, find the length
of the longest valid (well-formed) parentheses substring.
for <code>"(()"</code>, the longest valid parentheses substring
is <code>"()"</code>, which has length = 2.
another example is <code>")()())"</code>, where the longest valid
parentheses substring is <code>"()()"</code>, which has length = 4.
也就是說要找到最長的子串滿足比對規則。
算法思路,建立兩個數組pre[]和post[],生成規則如下:
pre數組:從前向後周遊原字元串s,若該下标i所對應的字元為‘(‘,則
:(1)若i為0,pre[i]=1;(2)若pre[i-1]<0,pre[i]=1(3)其餘情況,pre[i]=pre[i-1]+1;
post數組:從後向前周遊原字元串s,若該下标i所對應的字元為‘)‘,則:(1)若i為s.length-1,post[i]=1;(2)若post[i+1]<0,pre[i]=1(3)其餘情況,pre[i]=pre[i+1]+1;
例如:字元串")()())"的pre數組為 -1 1 0 1 0 -1,post數組為2
1 2 1 2 1
然後在pre數組中從後向前找到第一個值為0的下标,若沒有,則從pre數組中找出的最長子串為0,若找到,再向前找出第一個小于0的下标,或者全部大于0,此時下标遞減到0,則從pre數組中找出的最長子串的長度就是這兩個下标的內插補點。
同理,在post數組中從前向後找第一個值為0的下标,然後再找第一個值小于0的下标或者下标到s.length-1,從post數組中找到的子串長度即這兩個下标的內插補點。
是以,滿足條件的最長子串的長度就是從pre數組和post數組中找到的長度的最大值。
因為算法中周遊了兩次原字元串,一次pre數組和一次post數組,是以時間複雜度為o(n),空間複雜度為兩個數組pre和post,為o(n)

////////////////////////////////////////////////////////////////////////////////////////////分割線/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
看了一下網上的做法,轉載一下:
轉自
這道題可以用一維動态規劃逆向求解。假設輸入括号表達式為string s,維護一個長度為s.length的一維數組dp[],數組元素初始化為0。
dp[i]表示從s[i]到s[s.length -
1]包含s[i]的最長的有效比對括号子串長度。則存在如下關系:
dp[s.length - 1] = 0;
i從n - 2 -> 0逆向求dp[],并記錄其最大值。若s[i] == ‘(‘,則在s中從i開始到s.length -
1計算dp[i]的值。這個計算分為兩步,通過dp[i + 1]進行的(注意dp[i + 1]已經在上一步求解):
在s中尋找從i + 1開始的有效括号比對子串長度,即dp[i + 1],跳過這段有效的括号子串,檢視下一個字元,其下标為j = i
+ 1 + dp[i + 1]。若j沒有越界,并且s[j] == ‘)’,則s[i ... j]為有效括号比對,dp[i] =dp[i + 1] +
2。
在求得了s[i ... j]的有效比對長度之後,若j + 1沒有越界,則dp[i]的值還要加上從j +
1開始的最長有效比對,即dp[j + 1]。