给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
输入: s = "(()"
输出: 2
解释: 最长有效括号子串是 "()"
示例 2:
输入: s = ")()())"
输出: 4
解释: 最长有效括号子串是 "()()"
示例 3:
输入: s = ""
输出: 0
解法1:暴力解法
求出所有偶数长度的子串,然后逐个判断子串是否有效。
func longestValidParentheses1(s string) int {
for i := len(s); i > 0; i-- {
if i&1 == 1 {
continue
}
if isNSubStrValid(s, i) {
return i
}
}
return 0
}
func isNSubStrValid(s string, length int) bool {
for i := 0; i < len(s)-length+1; i++ {
subStr := s[i : i+length]
if isValid(subStr) {
return true
}
}
return false
}
func isValid(s string) bool {
var left int
for _, c := range s {
switch c {
case '(':
left++
case ')':
left--
}
if left < 0 {
return false
}
}
return left == 0
}
解法2
利用栈,栈底元素表示及分割值。
func longestValidParentheses(s string) int {
var maxLength int
var stack = make([]int, 0)
stack = append(stack, -1)
for idx, c := range s {
switch c {
case '(':
stack = append(stack, idx)
case ')':
//出栈
stack = stack[:len(stack)-1]
if len(stack) == 0 {
stack = append(stack, idx)
} else {
//现在的位置减去上一个左括号的位置 即有效长度
length := idx - stack[len(stack)-1]
if length > maxLength {
maxLength = length
}
}
}
}
return maxLength
}
解法3
动态规划
func longestValidParentheses(s string) int {
maxAns := 0
dp := make([]int, len(s))
for i := 1; i < len(s); i++ {
if s[i] == ')' {
if s[i-1] == '(' {
if i >= 2 {
dp[i] = dp[i - 2] + 2
} else {
dp[i] = 2
}
} else if i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] == '(' {
if i - dp[i - 1] >= 2 {
dp[i] = dp[i - 1] + dp[i - dp[i - 1] - 2] + 2
} else {
dp[i] = dp[i - 1] + 2
}
}
maxAns = max(maxAns, dp[i])
}
}
return maxAns
}
func max(x, y int) int {
if x > y {
return x
}
return y
}