算法32. Longest Valid Parentheses

32. Longest Valid Parentheses
Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

Example 1:

Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"

Example 2:

Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"

一個(gè)只有“(”與“)”的字符串,找到最長(zhǎng)的成對(duì)的子串。

算法3(無重復(fù)子串)、算法5(回文子串)都是找子串的,對(duì)于字符串的算法,都離不開遍歷。
思路一,暴力遍歷。在算法20中,也是求符號(hào)是否成對(duì),其中一個(gè)思路是用一個(gè)stack記錄遍歷過的符號(hào),利用stack先進(jìn)后出的特性,與后面的符號(hào)進(jìn)行配對(duì)。在這道題中也適用,但是這道題求最長(zhǎng)的一個(gè),所以暴力遍歷出所有的子串,然后分別去判斷是否合法,記錄最長(zhǎng)的長(zhǎng)度??臻g復(fù)雜度最壞情況下,需要裝n-1個(gè)符號(hào),即n-1個(gè)符號(hào)都相同,那么空間復(fù)雜度為O(n)。時(shí)間復(fù)雜度,遍歷出所有子串為O(n2),判斷是否合法再乘以n,故為O(n3)。

思路二:
也是使用stack去判斷是否配對(duì),但是沒必要遍歷出全部子串。題目要求一個(gè)配對(duì)返回長(zhǎng)度2,我們先把-1加入到棧中,遍歷字符串,如果是左括號(hào),把位置i加入到stack中。如果遇到右括號(hào),stack出棧一位,如果此時(shí)stack為空,表示不合法;使用i - stack.pop() ,就是當(dāng)前配對(duì)的長(zhǎng)度。為了計(jì)算后續(xù)是否配對(duì),需要再將當(dāng)前位置i入棧。這個(gè)算法的話,只需要遍歷一次,故時(shí)間復(fù)雜度為O(n)。最壞的空間復(fù)雜度為O(n),原因與思路一相同。

以下為代碼:

public int longestValidParentheses(String s) {
    int maxLen = 0;
    Stack<Integer> stack = new Stack<Integer>();
    stack.push(-1);

    for (int i = 0; i < s.length(); i++) {
        if('(' == s.charAt(i)) {
            stack.push(i);
        } else {
            stack.pop();
            if(stack.isEmpty()) {// 這種情況肯定不合法
                stack.push(i);
            } else {// 配上對(duì)了
                maxLen = Math.max(maxLen, i - stack.peek());
            }
        }
    }

    return maxLen;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容