32. 最长有效括号(困难 栈 字符串)

32. 最长有效括号

给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

示例 1:

输入:s = “(()”
输出:2
解释:最长有效括号子串是 “()”
示例 2:

输入:s = “)()())”
输出:4
解释:最长有效括号子串是 “()()”
示例 3:

输入:s = “”
输出:0

提示:

0 <= s.length <= 3 * 104
s[i] 为 ‘(’ 或 ‘)’

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析

匹配括号之类的题容易想到利用栈或者动态规划,这里采用栈和正序逆序两次遍历的方法,动态规划可以参考官方题解。
方法一:栈
思路是遍历字符串每个字符,在栈中储存所有 “(” 的下标,每次遇到 “)” 就 pop 一个下标,此时栈顶的下标与当前遍历到的下标之差即为当前连续的有效括号的长度,需要注意当前连续的有效括号不一定是最长的,需要跟之前记录的最长长度进行比较。
由于要用到栈顶的数字记录长度,所以预处理栈中储存 -1。
方法二:两次遍历
优化空间复杂度为 O(1)
思路:首先,有效括号的左右括号一定是相等的;其次,单独的右括号(没有左括号匹配)一定是不能算在有效括号里的,并且如果出现这种右括号,可以作为连续有效括号的“分割符”。
那么我们可以这么考虑,用两个变量 left 和 right 分别记录左右括号的数量,从左到右遍历字符串,有效的括号一定是先以一个左括号开始,以一个右括号结束,因此所有的有效括号开始时 left 一定是大于 right 的,当 left = right 时,记录下当前最长有效括号的长度(用已经记录的长度与 2 * right 相比),然后继续遍历,如果遇到 right > left 的情况,说明出现“分割符”,前面的有效括号不可能与后面的连续,令 left = right = 0,重新记录。
对于上述思路,可以发现对于 “(()” 这种以多个左括号开始以少个右括号结束的情况,因为没有 left = right 出现,所以无法得到有效括号长度,这种情况可以使用反向遍历,先记录右括号的数量再记录左括号的数量即可。

题解(Java)

方法一:

class Solution {
   
    public int longestValidParentheses(String s) {
   
        int ans = 0;
        Deque<Integer> stack = 

你可能感兴趣的:(leetcode)