不是吧不是吧,2025年了还有人不会括号匹配?

引言

大家好啊,我是前端拿破轮😁。

跟着卡哥学算法有一段时间了,通过代码随想录的学习,受益匪浅,首先向卡哥致敬🫡。

但是在学习过程中我也发现了一些问题,很多当时理解了并且AC的题目过一段时间就又忘记了,或者不能完美的写出来。根据费曼学习法 ,光有输入的知识掌握的是不够牢靠的,所以我决定按照代码随想录的顺序,输出自己的刷题总结和思考 。同时,由于以前学习过程使用的是JavaScript,而在2025年的今天,TypeScript几乎成了必备项,所以本专题内容也将使用TypeScript,来巩固自己的TypeScript语言能力。

题目信息

有效的括号

leetcode题目链接

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

有效字符串需满足:

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

题目分析

本题是栈的应用的最经典的题目。有效括号的匹配,对于熟悉栈的同学来说此题的解法并不难。本文想要分析的关键是,为什么别人一看到这个题就会想到使用栈这种数据结构?为什么我们就想不到呢?很多同学可能会说,别人刷到过这个题呗。这确实是一个原因,而且是很重要的原因。当然也有可能根据leetcode的题目分类,这道题目被划归到栈里面,当然要使用栈了。这些都是原因,但是不是本质原因。从根本上来说,是因为本题题目中的特征符合栈后进先出(LIFO)的特点 。括号进行匹配的时候,最后出现的左括号,却要最先匹配右括号,这不就是典型的栈的特征吗。所以掌握了根本原因后,以后我们在遇到没有见过的题目时,才能判断出解题方法。

本题整体上的思路就是,从左往右遍历括号字符串,如果是左括号,则入栈,如果是右括号,则将栈顶元素弹出,判断两者是否匹配。如果不匹配,直接剪枝返回false。如果匹配,则接着往后扫描。直到最后,判断辅助栈是否为空。如果栈非空,则说明有多余的左括号,不匹配。否则匹配。

这里面除了整体上使用栈的思路外,还有两个点需要注意。

  1. 如何判断一个字符串是左括号还是有括号

  2. 如何判断两个括号是否匹配

对于1,简单做法可以直接用相等符===和逻辑运算符||来进行判断。比如if(c === '{' || c === '[' || c === '(')来进行判断,也可以写一个Set哈希表来判断,比如const set = new Set('{', '[', '('),然后利用APIset.has()来判断,如果在set中,就是左括号。由于题目说到整个字符串只有左右括号,所以如果不在set中,一定是右括号。

对于2,可以针对不同的情况分别进行判断,比如if(c === '}')的情况下再判断栈顶弹出的元素是不是},但是这样就会导致if-else嵌套过深,导致圈复杂度过高,可读性也会降低。另一种方式是使用一个对象,会二维数组,保存左右括号之间的对应关系。

最合理的方案是使用哈希表Map,可以同时解决1和2的问题。因为Map拥有Set的功能,而且还能存储键值对,直接一步解决了两个问题。具体可以看题解部分。

题解

ts 复制代码
function isValid(s: string): boolean {
    // map对象存储映射关系
    const map = new Map([
        ['}', '{'],
        [']', '['],
        [')', '(']
    ]);

    // 辅助栈
    const stack = [];
    
    // 遍历字符串
    for (let c of s) {
        // 如果不在map中,一定是左括号,直接入栈
        if (!map.has(c)) {
            stack.push(c);
        } else {
            // 如果c在map中,说明c是右括号,将栈顶元素弹出
            const left = stack.pop();
            // 判断栈顶元素是不是当前右括号匹配的左括号,不匹配直接剪枝
            if (left !== map.get(c)) return false;
        }
    }
    // 最后结束后要根据栈是否为空
    return stack.length === 0;
};

时间复杂度: <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n ) O(n) </math>O(n), 只需要遍历一次字符串。

空间复杂度: <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n ) O(n) </math>O(n),需要问题规模的辅助栈,还有常数级别的map对象空间。总体是 <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n ) O(n) </math>O(n)。

总结

本题是栈最经典的题目,因为括号匹配的后进先出 的特点和栈完美吻合。在处理过程中还要用到map对象来存储映射关系。以及最后一定要记得判断辅助栈是否为空 。这一点很容易被忽略。很多同学遍历完发现都匹配就直接返回true,没有考虑到左括号可能多余的情况。

好了,这篇文章就到这里啦,如果对您有所帮助,欢迎点赞,收藏,分享👍👍👍。您的认可是我更新的最大动力。由于笔者水平有限,难免有疏漏不足之处,欢迎各位大佬评论区指正。

往期推荐✨✨✨

我是前端拿破轮,关注我,一起学习前端知识,我们下期见!

相关推荐
sali-tec1 小时前
C# 基于halcon的视觉工作流-章29-边缘提取-亚像素
开发语言·图像处理·算法·计算机视觉·c#
屁股割了还要学2 小时前
【数据结构入门】堆
c语言·开发语言·数据结构·c++·考研·算法·链表
拾光拾趣录9 小时前
基础 | HTML语义、CSS3新特性、浏览器存储、this、防抖节流、重绘回流、date排序、calc
前端·面试
阿群今天学习了吗9 小时前
“鱼书”深度学习进阶笔记(3)第四章
人工智能·笔记·python·深度学习·算法
IT猿手9 小时前
2025年最新原创多目标算法:多目标酶作用优化算法(MOEAO)求解MaF1-MaF15及工程应用---盘式制动器设计,提供完整MATLAB代码
算法·数学建模·matlab·多目标优化算法·多目标算法
小高00713 小时前
协商缓存和强缓存
前端·javascript·面试
数据智能老司机13 小时前
图算法趣味学——最大流算法
数据结构·算法·云计算
秋难降13 小时前
【数据结构与算法】———深度优先:“死磕 + 回头” 的艺术
数据结构·python·算法
数据智能老司机13 小时前
图算法趣味学——图着色
数据结构·算法·云计算
码出极致13 小时前
MySQL 与 MongoDB 深度对比:从数据模型到实战场景的核心差异解析
后端·面试