要找到只包含左括号和右括号的字符串中最长的有效括号子串的长度,我们可以使用栈或动态规划的方法。这里我将为你提供动态规划的解决方案。
动态规划的思路是,我们遍历整个字符串,对于每个位置,我们维护一个数组 dp,其中 dp[i] 表示以第 i 个字符结尾的最长有效括号子串的长度。
遍历字符串时,我们需要考虑以下几种情况:
如果当前字符是左括号,那么它不能形成有效括号子串,所以 dp[i] = 0。
如果当前字符是右括号,我们需要看其前面是否有对应的左括号可以匹配。如果前面没有左括号,那么 dp[i] = 0。如果前面有左括号,那么我们需要看左括号之前的子串是否也是有效括号子串。如果是,那么 dp[i] 的值就是左括号之前的有效子串长度加上当前右括号和前面的左括号。
但是,这里还有一个问题:如何快速找到左括号之前的有效子串长度?我们可以使用一个栈来辅助解决这个问题。当遇到左括号时,我们将其索引压入栈中;当遇到右括号时,如果栈不为空,说明有左括号可以匹配,我们弹出栈顶元素(即左括号的索引),并计算当前有效子串的长度。如果栈为空或者栈顶元素之前有更长的有效子串,我们还需要加上那部分长度。
下面是具体的实现步骤:
初始化一个空栈 stack 和一个长度为 n(字符串长度)的数组 dp,其中 dp[i] 初始值都为 0。
遍历字符串的每个字符:
如果当前字符是左括号,将其索引压入栈中。
如果当前字符是右括号:
如果栈为空,说明没有左括号可以匹配,dp[i] = 0。
否则,弹出栈顶元素,记为 leftIndex。
如果栈不为空,说明 leftIndex 之前有更长的有效子串,我们需要加上那部分长度,即 dp[i] = dp[leftIndex - 1] + 2。
如果栈为空,说明 leftIndex 就是当前有效子串的起点,dp[i] = 2。
还需要考虑 leftIndex 之前的子串是否有更长的有效子串,如果有,则 dp[i] += dp[leftIndex - 1]。
遍历完整个字符串后,dp 数组中的最大值就是最长的有效括号子串的长度。
下面是 Python 代码实现:
python复制代码 def longestValidParentheses(s): stack = [] dp = [0] * len(s) max_length = 0 for i in range(len(s)): if s[i] == '(': stack.append(i) else: if stack: left_index = stack.pop() if stack: dp[i] = dp[left_index - 1] + 2 else: dp[i] = 2 if left_index > 0: dp[i] += dp[left_index - 1] max_length = max(max_length, dp[i]) return max_length
这个算法的时间复杂度是 O(n),其中 n 是字符串的长度。我们只需要遍历一次字符串,并使用栈来辅助计算。空间复杂度也是 O(n),用于存储 dp 数组和栈。