LeetCode 32:最长有效括号 —— 栈 + 标记法 题解

LeetCode 32:最长有效括号 ------ 栈 + 标记法 题解

🔗 题目链接

👉 https://leetcode.cn/problems/longest-valid-parentheses/

📖 题目概要

给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(连续、合法)括号子串的长度。

  • 有效括号:必须成对、顺序正确、连续
  • 示例:"(()" → 输出 2;")()())" → 输出 4

✅ 本题解法:栈 + 标记法(你的 AC 代码思路)

核心思想

  1. 用栈记录所有匹配成功的括号位置
  2. 用mask 数组标记匹配成功的位置为 1
  3. 最后遍历 mask 数组,找最长连续 1 的长度,即为答案

💡 详细解题思路

1. 算法步骤

  • 第一步 :遍历字符串,遇到 ( 就把下标压入栈
  • 第二步 :遇到 ) 时,如果栈不为空,说明匹配成功
    • 弹出栈顶下标 j
    • 把 mask[j] 和 mask[i] 都标记为 1
  • 第三步 :遍历 mask 数组,统计最长连续 1的长度,就是最长有效括号长度

2. 为什么这个方法正确?

  • 只有真正成对匹配的括号才会被标记 1
  • 有效括号一定是连续一段,所以直接求最长连续 1 即可
  • 时间、空间都很优秀,逻辑直观易懂

✅ AC 代码(你的原版代码,可直接提交)

java 复制代码
class Solution {
    public int longestValidParentheses(String s) {
        int len = s.length();
        if(len <= 1) return 0;
        char[] ss = s.toCharArray();
        int[] mask = new int[len];
        Deque<Integer> stack = new LinkedList<Integer>();
        
        // 第一步:栈匹配括号,标记合法位置
        for(int i=0;i<len;i++) {
            if(ss[i] == '(') {
                stack.push(i);
            } else {
                if(!stack.isEmpty()) {
                    int j = stack.pop();
                    mask[i] = 1;
                    mask[j] = 1;
                }
            }
        }
        
        // 第二步:找最长连续 1 的长度
        int res = 0;
        int cur = 0;
        for(int i=0;i<len;i++) {
            if(mask[i] == 1) {
                cur++;
                res = Math.max(res,cur);
            } else {
                cur = 0;
            }
        }
        return res;
    }
}

⏱️ 复杂度分析

指标 复杂度 说明
时间复杂度 O(n) 仅两次线性遍历
空间复杂度 O(n) 栈 + mask 数组开销

📌 核心总结

  1. 栈用来匹配括号,记录下标
  2. mask 数组用来标记合法位置
  3. 最后统计最长连续 1,就是答案
  4. 思路简单、好写、不易错,面试首选写法

📝 面试高频问答

1. 为什么要存下标,不存字符?

因为我们需要标记位置,最后统计连续合法段长度。

2. 为什么最后要遍历 mask 数组?

因为有效括号一定是连续的,最长连续 1 就是最长有效长度。

3. 这个方法和纯 DP 比有什么优势?

  • 逻辑更简单
  • 不用推导 DP 方程
  • 代码短、不容易写错
相关推荐
代码什么用7 小时前
Spring基础使用
java·后端·spring
信奥卷王7 小时前
[GESP202609 六级] 分树规划
算法
Su米苏7 小时前
Spring AI 中MCP 与普通 @Tool的区别
java·人工智能·spring
夏幻灵8 小时前
LeetCode 21:合并两个有序链表——双指针与哑节点详解
算法·leetcode·链表
码云数智-园园8 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
老板一杯拿铁8 小时前
Java 异常体系详解:从字节码原理到最佳实践
java
蜗牛互联网8 小时前
Java 17 HttpClient调用文件转写API的超时与失败回退
java·人工智能·后端
禾小西8 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨8 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言