首先定义了三个变量 left、right 和 maxLength,分别表示当前子串中左括号数、右括号数和最大有效括号子串长度。
然后从左向右遍历字符串,依次统计左右括号数,并判断当前子串是否为有效括号子串。如果是,则更新最大有效括号子串长度;否则,左右括号数清零,继续寻找下一个子串。从左向右遍历是针对()()()、()(())以及(()())这种左右括号数相等的情况;
针对((())这种左括号数大于右括号数的情况,只从左向右遍历的话,因为left>right,所以会导致始终匹配不到有效括号,所以要接着从右向左遍历字符串,来找到所有未匹配的右括号并计算最长有效括号子串的长度,遍历过程与从左向右遍历类似。
需要注意的是,重新遍历(开始从右向左遍历)需要将left,right置为初始值。
最后返回最大有效括号子串的长度。
函数中还定义了一个 max() 函数,用于返回两个数中较大的一个。
时间复杂度O(n),空间复杂度O(1)
// 给定一个只包含 '(' 和 ')' 的字符串,找出最长的有效(格式正确且连续)括号子串的长度。
func longestValidParentheses(s string) int {
// 初始化左右括号数和最大有效括号子串长度
left, right, maxLength := 0, 0, 0
// 从左向右遍历字符串
for i := 0; i < len(s); i++ {
// 如果当前字符是左括号,则left累加
if s[i] == '(' {
left++
} else {
// 如果当前字符是右括号,则right累加
right++
}
// 如果左右括号数相等,表示当前子串是一个有效括号子串
if left == right {
maxLength = max(maxLength, 2 * right) // 更新最大有效括号子串长度
} else if right > left {
// 如果右括号数大于左括号数,表示当前子串已经不是有效括号子串了,左右括号数清零,重新开始计数
left, right = 0, 0//重新遍历(开始从右向左遍历)需要将left,right置为初始值。
}
}
// 从右向左遍历字符串,与从左向右遍历类似
left, right = 0, 0
for i := len(s) - 1; i >= 0; i-- {
if s[i] == '(' {
left++
} else {
right++
}
if left == right {
maxLength = max(maxLength, 2 * left)
} else if left > right {
left, right = 0, 0
}
}
return maxLength // 返回最大有效括号子串长度
}
// 返回两个数中较大的一个
func max(x, y int) int {
if x > y {
return x
}
return y
}