Lever's Castle

32. 最长有效括号

May 04, 2020

https://leetcode-cn.com/problems/longest-valid-parentheses/

解:

func longestValidParentheses(s string) int {
    var stack []int
    var lastStart, maxLen int
    for i, item := range s {
        if string(item) == "(" {
            stack = append(stack, i)
        } else {
            if len(stack) > 0 {
                stack = stack[:len(stack) - 1]
                var length int
                if len(stack) == 0 {
                    length = i - lastStart + 1
                } else {
                    length = i - stack[len(stack) - 1]
                }
                if length > maxLen {
                    maxLen = length
                }
            } else {
                lastStart = i + 1
            }
        }
    }
    return maxLen
}

思考过程

括号的匹配,立马就会想到出栈入栈的过程,遇到 ”(” 入栈,遇到 ”)” 出栈。当栈为空时,遇到 ”)“,是势必无法匹配出栈的,因此这种情况我们需要从这里断开,前面匹配的结果,与后面的匹配情况已经无关了(因为已经不满足连续的条件了),重新开始新的入栈、出栈操作。

再来想下正常匹配的情况,正常匹配意味着会有一个 ”(” 出栈,则这段正常匹配的字符串的长度,可以通过出栈后新的栈顶的 ”(” 在字符串 s 中所处的位置离当前最后一个 ”)” 的距离得出。比如 ”(()“,栈应该是这样的 —— [”(”, ”(”],遇到 ”)” 后,栈顶的 ”(” 出栈,栈变成了 [”(”],而此时栈中的栈顶元素对应 s 中的索引为 0 的元素,此时 ”)” 的索引为 2,则字符串的长度可以计算得出 2 - 0 = 2。

还有一种情况,当最后一个 ”(” 也匹配出栈了,我们怎么计算字符串的长度呢?这里我定义了一个 lastStart 来表示本次栈匹配的开始位置(中间可能中断过)。当栈为空后,字符串的长度可以通过当前 ”)” 的位置,与本次匹配的起始位置的距离计算得出。

每次将长度进行比较,留下较大的值,最终得到的就是最长的子串。


Lever

痕迹
没有过去,就没法认定现在的自己