力扣hot100 20.有效的括号 解析

题目描述

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1:

**输入:**s = "()"

**输出:**true

示例 2:

**输入:**s = "()\[\]{}"

**输出:**true

示例 3:

**输入:**s = "(]"

**输出:**false

示例 4:

**输入:**s = "(\[\])"

**输出:**true

示例 5:

**输入:**s = "()"

**输出:**false

提示:

  • 1 <= s.length <= 104
  • s 仅由括号 '()[]{}' 组成

思路解析

一、题目到底在检查什么?

给你一个字符串,只包含:

( ) { } [ ]

问你一句话:

括号是否"合法配对 + 正确嵌套"

合法的例子

复制代码
() ()[]{} {[()]} 

不合法的例子

复制代码
(] ([)] ((( 

二、什么叫「合法」?

合法 ≠ 数量相等

合法 = 三条规则同时满足


规则 1:左括号必须被右括号关闭

复制代码

(

不合法(没关)


规则 2:右括号必须匹配同类型的左括号

复制代码

(]

类型不对


规则 3:括号必须 后开先关(嵌套顺序)

([)]

你开的是:

复制代码

( → [

你关的时候却是:

) → ]

顺序错了


三、为什么「栈」是唯一正确模型?


括号的本质是「最近的要先关」

例子:

复制代码

{ [ ( ) ] }

执行顺序:

  1. 开 {

  2. 开 [

  3. 开 (

  4. 关 ) → 只能关最近的 (

  5. 关 ] → 只能关 [

  6. 关 } → 只能关 {

这就是一句话:

后进先出(LIFO)

而 栈 的特性就是:

复制代码

后进先出


如果不用栈,会发生什么?

比如用变量记录?

  • 你最多记一个

  • 一旦嵌套多层就崩了

所以 栈是唯一自然模型


四、整体算法思路

从左到右扫描字符串

  • 遇到左括号:压栈

  • 遇到右括号:

    • 看栈顶是不是对应的左括号

    • 是 → 弹出

    • 不是 → 立刻非法

      最后:栈必须为空


代码实现

java 复制代码
class Solution {

    /**
     * 判断一个只包含 () {} [] 的字符串是否是「有效括号」
     */
    public boolean isValid(String s) {

        // ① 如果字符串长度是奇数:
        //    括号一定无法成对出现,直接返回 false(提前剪枝)
        if (s.length() % 2 == 1) {
            return false;
        }

        // 字符串总长度
        int n = s.length();

        // ② 建立「右括号 -> 左括号」的映射关系
        //    作用:当遇到右括号时,能立刻知道它期望匹配的左括号是什么
        Map<Character, Character> mp = new HashMap<>();
        mp.put(')', '(');
        mp.put('}', '{');
        mp.put(']', '[');

        // ③ 使用栈(Deque)来存放尚未被匹配的左括号
        //    栈的特点是:后进先出,正好符合括号"后开的先关"的规则
        Deque<Character> stack = new LinkedList<>();

        // ④ 从左到右遍历字符串中的每一个字符
        for (int i = 0; i < n; i++) {

            // 取出当前字符
            char ch = s.charAt(i);

            // ⑤ 如果当前字符是右括号
            //    (因为 mp 中只存了右括号作为 key)
            if (mp.containsKey(ch)) {

                // ⑥ 出现右括号时,必须满足两个条件:
                //    1)栈不能是空的(否则说明没有对应的左括号)
                //    2)栈顶元素必须是这个右括号对应的左括号
                if (stack.isEmpty() || stack.peek() != mp.get(ch)) {
                    // 只要有一个条件不满足,说明括号不合法
                    return false;
                } else {
                    // ⑦ 如果匹配成功:
                    //    当前这一对括号合法,弹出栈顶左括号
                    stack.pop();
                }

            } else {
                // ⑧ 如果当前字符是左括号:
                //    无法立即判断是否合法,只能先压入栈中
                //    等后续遇到右括号时再进行匹配
                stack.push(ch);
            }
        }

        // ⑨ 遍历结束后:
        //    如果栈为空,说明所有左括号都被正确匹配
        //    如果栈不为空,说明存在多余的左括号,字符串不合法
        return stack.isEmpty();
    }
}
相关推荐
非优秀程序员2 小时前
第05章 播放器大战,暴风、快播与那一夜|《互联网产品恩仇录》
算法
非优秀程序员2 小时前
第04章 邮箱大战,163 与 QQ 的暗战|《互联网产品恩仇录》
java·vue.js·架构
知已难寻3 小时前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
文丑颜不良啊5 小时前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang6 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
聪明的笨猪猪6 小时前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程
愿有所息7 小时前
记一次 ARM64 + JDK8 上 fastjson2 的诡异数据错乱
java
秋饼7 小时前
MCP 2026-07-28 无状态协议大改版:Spring AI 2.1 多轮往返请求与网关路由落地
java·ai·技术分享·后端开发
SL_staff8 小时前
JVS-BI 实战:业务人员如何用零代码 ELT + 可视化配置构建实时经营分析闭环
java·spring·全栈