1. 程式人生 > >Leetcode 32:最長有效括號(最詳細的解法!!!)

Leetcode 32:最長有效括號(最詳細的解法!!!)

給定一個只包含 '('')' 的字串,找出最長的包含有效括號的子串的長度。

示例 1:

輸入: "(()"
輸出: 2
解釋: 最長有效括號子串為 "()"

示例 2:

輸入: ")()())"
輸出: 4
解釋: 最長有效括號子串為 "()()"

解題思路

這種問題我們首先想到的解決思路是通過棧。我們首先遍歷一遍s,判斷遍歷到的字元ch是不是(,如果是的話,我們就將ch.index加入到棧中,例如

( ( )
↑
stack: 0

如果遍歷到的元素是),且棧不為空棧頂元素是(,我們就出棧。

( ( )
    ↑
stack: 0

否則如果棧為空,我們就將ch.index

入棧。這樣掃面完一輪,我們的棧裡面存放的就是沒有匹配到的位置。例如

stack: | 0 3 7 13 |
      -1         len(s)

此時我們只要遍歷stack,找到兩兩元素之間隔最大的距離即可。

class Solution:
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        s_len, stack = len(s), list()
        for i, ch in enumerate
(s): if ch == '(': stack.append(i) elif stack and s[stack[-1]] == '(': stack.pop() else: stack.append(i) if not stack: return s_len stack = [-1] + stack + [s_len] for i,val in enumerate
(stack[1:]): stack[i] = val - stack[i] - 1 return max(stack[:-1])

這個問題也可以通過動態規劃來做,而且思路也非常清晰。我們定義 f ( i ) f(i) 表示當前位置i結尾的最長有效括號的長度,那麼

  • f ( i ) = f ( i 1 ) + 2     i f    s [ i 1 f ( i 1 ) ] = = ( f(i)=f(i-1)+2\ \ \ if \ \ s[i-1-f(i-1)]=='('
  • f ( i ) = f ( i ) + f ( i f ( i ) ) f(i)=f(i)+f(i-f(i))

稍微說明一下,因為 f ( i ) f(i) 為此時的最大長度,那麼i-1-f(i)就表示之前還未匹配的(,例如

( ) ( ( ) )
    ↑     i

如果我們的i在這個位置,那麼i-1-f(i)就是箭頭所指的位置。由於此時箭頭所指的位置是(,所以我們應該將f(i)+2=4。但是我們此時得到只是一個小區間內的最大值,我們應該還要加上以箭頭前一位置結尾的最大長度,那麼此時我們得到的解過就是以i結尾的最大長度。

最後這個演算法還有一個小問題,如果我們此時i(怎麼辦?我們上面的f(i)+2就是錯誤的。所以我們乾脆不考慮這種情況,只考慮)即可。那麼只考慮)情況是合理的嗎?合理,因為最長有效括號一定是以)結尾。

class Solution:
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        s_len, result = len(s), 0
        if s_len < 2:
            return 0
        mem = [0]*s_len
        for i in range(1, s_len):
            if s[i] == ')':
                left = i-1-mem[i-1]
                if left >= 0 and s[left] == '(':
                    mem[i] = mem[i-1] + 2
                mem[i] += mem[i-mem[i]]
            result = max(result, mem[i])
        return result

reference:

https://leetcode.com/problems/longest-valid-parentheses/discuss/14126/My-O(n)-solution-using-a-stack

我將該問題的其他語言版本新增到了我的GitHub Leetcode

如有問題,希望大家指出!!!