题目描述
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"
示例 2:
输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"
示例 3:
输入:s = ""
输出:0
提示:
0 <= s.length <= 3 * 104
s[i] 为 '(' 或 ')'
思路
这个问题可以通过使用栈(Stack)来解决。栈是一种数据结构,它遵循"后进先出"(Last In First Out,LIFO)的原则,适用于需要保持元素顺序的场景。
解题思路如下:
-
我们使用一个栈来存储字符的索引,初始化时将-1(用于表示有效子串的起始位置)推入栈中。
-
我们从左到右遍历字符串的每个字符:
- 如果遇到左括号'(',将其索引推入栈中。
- 如果遇到右括号')',弹出栈顶元素表示匹配了一个括号,然后计算当前右括号的索引与新栈顶元素之间的距离,即有效子串的长度。这里的距离计算是基于当前右括号与上一个未匹配的左括号之间的距离。
-
在遍历过程中,栈中的元素始终表示上一个未匹配的左括号的索引。
-
遍历结束后,栈中剩下的元素对应于未匹配的左括号的索引,我们可以利用这些索引来计算可能的最长有效括号子串长度。
这个算法的关键在于使用栈来记录未匹配的左括号的位置,从而能够计算出连续的有效括号子串的长度。算法的时间复杂度是O(n),其中n是字符串的长度。
代码
scala
object Solution {
def longestValidParentheses(s: String): Int = {
val stack = scala.collection.mutable.Stack[Int]()
var maxLength = 0
// 初始值用于标记有效子串的起始位置
stack.push(-1)
for ((char, index) <- s.zipWithIndex) {
if (char == '(') {
stack.push(index)
} else {
stack.pop()
if (stack.isEmpty) {
stack.push(index)
} else {
maxLength = Math.max(maxLength, index - stack.top)
}
}
}
maxLength
}
def main(args: Array[String]): Unit = {
val s1 = "(()"
println(longestValidParentheses(s1)) // 输出 2
val s2 = ")()())"
println(longestValidParentheses(s2)) // 输出 4
val s3 = ""
println(longestValidParentheses(s3)) // 输出 0
}
}