关于Leecode 第二十道题个人见解(以JS解决问题)

前言

此文章为本人第一次讲解算法,可能有些不完美,欢迎大家交流与指正

原题目

题目解析:

简单来说,这个题目就像是在检查一个人说话时用的括号是否正确一样。比如,如果说:“我今天(去超市买了[很多东西],然后回家)做饭。”这里的括号就是正确使用的,因为每种类型的括号都正确配对,并且按照正确的顺序闭合。如果括号使用错误,比如:“我今天(去超市买了[很多东西回家)做饭。”,那么括号就没有正确配对,说话的人可能需要重新组织语言。这个程序就是要自动检查这种括号的使用是否正确。

前置知识点:

Stack(栈):

栈(Stack)是一种基本的数据结构,它遵循后进先出(Last In, First Out,简称LIFO)的原则。这个概念在计算机科学中非常重要,因为它在很多算法和编程语言中都有应用。以下是栈的一些关键特点:

  1. 插入点固定:栈只允许在一端(称为“栈顶”,top)进行数据的添加或删除操作。

  2. 后进先出:最后添加到栈中的元素将是第一个被移除的元素。这就像一叠盘子,你总是先拿走最上面的盘子。

  3. 主要操作

    • 入栈(Push):将一个元素添加到栈顶。
    • 出栈(Pop):移除并返回栈顶的元素。
    • 查看栈顶元素(Peek/Top):查看但不移除栈顶的元素。
  4. 容量:有些栈有固定的大小,称为静态栈;而有些栈可以动态增长,称为动态栈。

  5. 应用场景

    • 函数调用:在编程中,每次函数调用时,新的函数调用会被压入一个隐式的“调用栈”中。
    • 括号匹配:检查代码或文本中的括号是否正确配对。
    • 撤销操作:在编辑器或绘图软件中,允许用户撤销最近的一系列操作。
  6. 实现方式:栈可以用数组或链表来实现。数组提供了快速的访问和修改,而链表则允许动态地增加栈的大小。

  7. 特点:栈是有序的,但不支持随机访问。你不能直接访问栈中间的元素,只能访问栈顶元素。

  8. 变体:有些栈的变体允许在两端添加或移除元素,称为双端栈(Deque)。

栈是一种非常有用的数据结构,因为它的简单性和在许多问题中自然出现的LIFO特性。在编程和算法设计中,栈经常被用来解决实际问题,比如解析表达式、处理回溯问题等。

.Map()

在JavaScript中,Map 是一种集合类型,用于存储键值对的集合,其中键可以是任何类型。Map 对象在ES6(ECMAScript 2015)中被引入,提供了一种更现代和灵活的方式来处理键值对集合,相较于传统的对象({}),它有以下几个特点:

  1. 键的多样性

    • 键可以是任何类型,包括对象、函数、Symbol等,而不仅仅是字符串或Symbol。
  2. 保持插入顺序

    • Map 对象中的元素会按照它们被添加的顺序进行迭代。
  3. 性能

    • 对于频繁增删键值对的场景,Map 通常提供比传统对象更好的性能。
  4. 内置方法

    • Map 提供了多种方法来操作集合,例如:
      • .set(key, value):添加一个新的键值对或更新现有键的值。
      • .get(key):根据键获取对应的值。
      • .has(key):检查Map中是否包含某个键。
      • .delete(key):删除指定的键值对。
      • .clear():移除Map中的所有键值对。
      • .size:返回Map中元素的数量。
  5. 迭代器

    • Map 对象是可迭代的,可以使用 for...of 循环或通过 .keys().values().entries() 方法进行迭代。
  6. 弱引用Map

    • 有一种特殊的 Map 叫做 WeakMap,它允许键是对象,并且当键不再被其他引用引用时,该键值对会自动从 WeakMap 中移除。
  7. 灵活性

    • 可以轻松地将 Map 转换为数组,例如使用 Array.from(map) 或扩展运算符 ...
  8. 用途

    • 用于需要快速查找、添加和删除键值对的场景,尤其是在键的类型多样或需要保持元素顺序时。

答案(源码及详细注释)

核心思想

这段代码是一个用于检查字符串中括号是否正确闭合的函数,其核心思想是使用栈(Stack)数据结构来跟踪最近遇到的开括号,并按照顺序检查闭括号是否正确匹配。以下是核心思想的详细解释:

  1. 映射关系建立

    • 使用 Map 对象建立一个映射关系,将每一种开括号('(', '[', '{')映射到对应的闭括号(')', ']', '}')。
  2. 栈的初始化

    • 创建一个空数组 stack 作为栈使用,用于存储尚未匹配的闭括号。
  3. 遍历字符串

    • 遍历输入字符串 s 的每个字符。
  4. 处理开括号

    • 如果当前字符是开括号,根据映射关系找到对应的闭括号,并将其推入栈中。
  5. 匹配闭括号

    • 如果当前字符是闭括号:
      • 尝试从栈中弹出一个元素(pop())。
      • 如果栈为空(没有对应的开括号),或者弹出的元素与当前闭括号不匹配,则字符串无效,返回 false
  6. 检查栈是否为空

    • 遍历结束后,如果栈不为空,说明有未匹配的开括号,返回 false
    • 如果栈为空,说明所有的开括号都找到了对应的闭括号,字符串有效,返回 true
  7. 优化

    • 最后两个 if 语句检查栈是否为空,实际上只需要一个。如果栈不为空,直接返回 false;否则,返回 true

核心思想的关键在于使用栈来跟踪需要匹配的开括号,并确保它们按照正确的顺序与闭括号配对。这种算法利用了栈的后进先出(LIFO)特性,确保了最后遇到的开括号最先被匹配,这与括号匹配的自然顺序相符合。

通过这种方式,算法能够有效地检查字符串中的括号是否有效闭合,满足题目要求的三个条件:相同类型的左括号必须用相同类型的右括号闭合,左括号必须以正确的顺序闭合,每个右括号都必须有一个对应的相同类型的左括号。


 

  • 28
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值