【LeetCode 】: 32. 最长有效括号

32. 最长有效括号

问题描述:

给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。

题目链接:https://leetcode-cn.com/problems/longest-valid-parentheses/

示例1:

输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”

示例2:

输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”

思路1(暴力破解法):

在这种方法中对字符串中的每个偶数长度的字符串,都进行检测是否是一个有效的括号子串,检测方法使用栈的方法。因为遍历了所有偶数长度字串,所以时间复杂度太高,LeetCode上超时。

代码如下:

//判断子字符串是不是有效括号串
private boolean isValid(String s) {
    Stack<Character> stack = new Stack<>();
    for (int i = 0;i < s.length(); i++) {
        if (s.charAt(i) == '(') {
            stack.push(s.charAt(i));
        } else if (!stack.empty() && stack.peek() == '(') {
            stack.pop();
        }else {
            return false;
        }
    }
    return stack.empty();
}

//遍历所有子字符串,对所有字符串进行判断
public int longestValidParentheses(String s) {
    if (s == null && s.length() == 0)
        return 0;
    int max = 0;
    for (int i = 0;i < s.length(); i++) {
        for (int j = i+ 2; j <=s.length(); j+=2) {
            if (isValid(s.substring(i , j))){
                max = Math.max(max , j - i);
            }
        }
    }
    return max;
}

思路2(利用辅助栈判断):

与找到每个可能的子字符串后再判断它的有效性不同,我们可以用栈在遍历给定字符串的过程中去判断到目前为止扫描的子字符串的有效性,同时能的都最长有效字符串的长度。我们首先将 -1−1 放入栈顶。

  • 如果当前字符是( , 直接把当前字符入栈
  • 弹出栈顶元素。如果栈为空,就把当前元素入栈。若不为空,则把当前元素索引和栈顶索引做差,记录最大值。
  • 返回最大值即可

代码如下

 public int longestValidParentheses2(String s) {
     if (s == null || s.length() <= 1)
         return 0;
     int max = 0;
     int dp[] = new int[s.length()];
     for (int i = 1;i < s.length();i++) {
         if (s.charAt(i) == ')') {
             if (i - dp[i - 1] - 1 >= 0 && s.charAt(i - dp[i - 1] -1) == '(')
                 dp[i] = dp[i - 1] + 2;
             if (i - dp[i] >= 0)
                 dp[i] += dp[i - dp[i]];
         }
     }
     return max;
 }
思路3 动态规划:

我们定义一个dp[]数组,其中第i个元素代表当前下标为i的字符串结尾的最长有效子字符串的长度。
因为有效子字符串必定是以)结尾的,所以以(对应的字符下标对应的dp位置上全部先赋值为0。

  • 如果当前字符串是),那么如果s[i - dp[i-1] - 1] = '(',也就是说第i个字符和第i-dp[i-1]-1字符匹配,那么dp[i-1]就可以扩展,即dp[i] = dp[i-1] + 2
  • dp[i - dp[i]] 进行合并,把之前的有效括号串合并进来

代码如下:

public int longestValidParentheses2(String s) {
    if (s == null || s.length() <= 1)
        return 0;
    int max = 0;
    int dp[] = new int[s.length()];
    for (int i = 1;i < s.length();i++) {
        if (s.charAt(i) == ')') {
            if (i - dp[i - 1] - 1 >= 0 && s.charAt(i - dp[i - 1] -1) == '(')
                dp[i] = dp[i - 1] + 2;
            if (i - dp[i] >= 0)
                dp[i] += dp[i - dp[i]];
        }
    }
    return max;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值