leetcode32.最长有效括号(java)

题目
在这里插入图片描述
这道题需要仔细审题,开始的时候就做错了好几次,因为题目意思理解错了,理解成一个有效的括号最长为多少,或者有多少对匹配的字符串之类的。

思路一:栈
在这里插入图片描述
想要获取匹配括号的长度,应该是‘)’的下标,减去‘(’的前一个的下标。
所以提前入栈-1.
如果遇到‘(’,将下标入栈
如果遇到‘)’,将栈顶元素出栈,如果栈为空,则将该元素入栈,否则括号的最长长度为(当前元素下标-栈顶元素)与目前最长长度相比的最大值。

ans = Math.max(ans,i-stack.peek());

具体代码

class Solution {
    public int longestValidParentheses(String s) {
        if(s == null && s.length()==0){
            return 0;
        }
        Stack<Integer> stack = new Stack<>();
        stack.push(-1);
        int ans = 0;
        for(int i = 0;i < s.length();i++){
            if(s.charAt(i) == '('){
                stack.push(i);
            }else{
                stack.pop();
                if(stack.isEmpty()){
                    stack.push(i);
                }else{
                    ans = Math.max(ans,i-stack.peek());
                }
            }
        }
        return ans;

    }
}

时间复杂度:O(n)
空间复杂度:O(n)

思路二:
用left记录‘(’的个数,用right记录‘)’的个数,
从左往右遍历
如果两者相等,则长度为2left(或right)
如果right>left,则left=right=0;
从右往左遍历
如果两者相等,则长度为2
left(或right)
如果left>right,则left=right=0;

具体代码

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

    }
}

思路三:动态规划
dp[i]表示下标为i时有效括号长度。
从左往右遍历,遇到‘)’,判断前一个字符是不是‘(’,
若是:
如果i-2>=0,那么dp[i] = dp[i-2]+2;
否则:dp[i] = 2;
若前一个字符是‘)’,则判断下标i-i-dp[i-1]-1是否存在,该位置的字符是不是‘(’,
若是,i-i-dp[i-1]-2是否大于等于0,是则
dp[i] = dp[i-1]+dp[i-dp[i-1]-2]+2;
否则,
dp[i] = dp[i-1]+2;

具体代码

class Solution {
    public int longestValidParentheses(String s) {
        if(s == null || s.length()==0){
            return 0;
        }
        int[] dp = new int[s.length()];
        int max = 0;
        dp[0] = 0;
        for(int i = 1;i < s.length();i++){
            if(s.charAt(i) == '('){
                dp[i] = 0;
            }else{
                if(s.charAt(i-1)=='('){
                    dp[i] = i-2>=0?dp[i-2]+2:2;
                }else if(i - dp[i-1]-1>=0&&s.charAt((i - dp[i-1]-1))=='('){
                    dp[i] = i-dp[i-1]-2>=0?dp[i-1]+dp[i-dp[i-1]-2]+2:dp[i-1]+2;
                }
            }
            max = Math.max(max,dp[i]);
        }
        return max;
    }
}

参考资料
https://leetcode-cn.com/problems/longest-valid-parentheses/solution/zui-chang-you-xiao-gua-hao-by-leetcode/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值