32. Longest Valid Parentheses

本文探讨了一种高效算法来寻找给定字符串中最长的有效括号子串的长度。通过两次遍历,分别从前向后和从后向前,确保了括号匹配的正确性,并详细解释了算法的设计思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.
For "(()", the longest valid parentheses substring is "()", which has length = 2.
Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.
确实挺难的 
一开始的想法是这样的 一个有效的字符串肯定是以”(“开头的 那么就从每个”(“开始 遇到”(“就push进stack 
遇到”)” 分两种情况
1.stack如果是空的 说明没有对应的”(“ 目前为止的字符串无效 长度归零
2.如果stack不为空就pop一个”(“出来 长度+2
过程中求最大长度 比如输入是 “()((()))”
我们用i代表扫描的位置 
当i=1时 len=2
i=2,3,4时 因为没有对应的”)” len=2
i=5,6,7 len分别对应4,6,8
代码如下 
    public int longestValidParentheses(String s) {
        Stack<Character> stack = new Stack<>();
        int local = 0, len = 0;
        for (char c : s.toCharArray()) {
            switch (c) {
                case '(':
                    stack.push(c);
                    break;
                case ')':
                    if (!stack.isEmpty()) {
                        stack.pop();
                        local+=2;
                        len = Math.max(len, local);
                    } else {
                        local = 0;
                    }
                    break;
            }
        }
        return len;
    }
乍一看没什么问题 但是当输入是”()((()”时呢
返回结果是4 而不是2
因为我只判断了”)”无效的情况 长度会归零
没有判断”("无效的情况 也就是”(“没有对应的”)”的情况 也应该长度归零
而且也没有必要用stack 用left记录”(“的个数 用right记录”)”的个数 当left == right  len+=2*left就可以了
那该怎么修改呢 再从右到左扫描一遍  

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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值