伴你如风、护你如影|

xzh-yyds

园龄:3年9个月粉丝:0关注:2

leetcode32-最长有效括号

最长有效括号

  • dp

dp[i]表示以i为结尾的有效括号的最大长度,dp转移方程如下:

  1. 如果i是)且i-1是(,那么dp[i] = dp[i-2]+2
  2. 如果i是)且i-1是),且第i-dp[i-1]-1(,这样刚好能和第i个字符进行匹配。那么dp[i] = dp[i-dp[i-1]-2] + (i+1-(i-dp[i-1]-1))dp[i-dp[i-1]-2]+dp[i-1]+2。其中本段的长度为dp[i-1]+2,之前的部分长度为dp[i-dp[i-1]-2],可以与本段进行拼凑。
class Solution {
    public int longestValidParentheses(String s) {
        int n = s.length(), dp[] = new int[n], max = 0;
        for(int i = 1; i < n; i++){
            if(s.charAt(i) == ')'){
                if(s.charAt(i-1) == '(')    dp[i] = i >= 2 ? dp[i-2]+2 : 2;
                else if(i-dp[i-1] > 0 && s.charAt(i-dp[i-1]-1) == '(')   
                    dp[i] = dp[i-1]+2 + (i - dp[i-1] >= 2 ? dp[i-dp[i-1]-2] : 0);
                max = Math.max(max, dp[i]);
            }
        }
        return max;
    }
}

使用栈记录上一次匹配成功的位置。初始在栈中放入-1。
如果字符为(,那么直接放入栈中;如果字符为),那么需要将栈顶的元素pop出来。pop之后一旦堆栈为空,则需要将当前位置放入堆栈(堆栈为空则意味着本次匹配是个无效匹配,右括号多出一个,需要重新标记上次的下标)。然后本次的长度就是当前的坐标减去栈顶的元素

class Solution {
    public int longestValidParentheses(String s) {
        Deque<Integer> stk = new ArrayDeque<>();
        int max = 0;
        stk.push(-1);
        for(int i = 0; i < s.length(); i++){
            if(s.charAt(i) == '(')  stk.push(i);
            else{
                stk.pop();
                if(stk.isEmpty())   stk.push(i);
                max = Math.max(max, i-stk.peek());
            }
        }
        return max;
    }
}
  • 只记录左括号和右括号的数量

不需要维护dp数据或者栈,只去记录左括号和右括号的数量
当左括号和右括号数量相等时,更新最大值。当右括号的数量大于左括号的时候,说明在此之前的括号无法匹配,清空左右括号数量。
但是这时候有个问题,就是如果左括号的数量一直大于右括号,那么就一直无法更新最大值,所以需要从右向左再次进行遍历,规则相反。

class Solution {
    public int longestValidParentheses(String s) {
        int max = 0, left = 0, right = 0, n = s.length();
        for(int i = 0; i < n; i++){
            if(s.charAt(i) == '(')  left++;
            else    right++;
            if(left == right)   max = Math.max(max, 2*left);
            else if(right > left)   left = right = 0;
        }
        left = right = 0;
        for(int i = n-1; i >= 0; i--){
            if(s.charAt(i) == ')')  right++;
            else    left++;
            if(left == right)   max = Math.max(max, 2*left);
            else if(left > right)   left = right = 0;
        }
        return max;
    }
}

本文作者:xzh-yyds

本文链接:https://www.cnblogs.com/xzh-yyds/p/16597377.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   xzh-yyds  阅读(22)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开