返回

绝妙设计!Map助你优化匹配,解题如神!——力扣20题《有效的括号》

前端

如何高效判断括号的有效性:探索《有效的括号》

在编程的世界里,括号随处可见,它们帮助我们组织和分组代码块,让代码更具可读性和条理性。然而,在使用括号时,一个常见的问题出现了——如何确保括号的使用是有效的?

为了解决这个问题,力扣平台设计了第20题:《有效的括号》。这道题要求我们编写一个函数,判断给定字符串中的括号是否有效。那么,什么是有效的括号呢?简单来说,就是括号成对出现,每个左括号都能找到与之匹配的右括号。

例如,字符串"()"和"{}[]"都是有效的括号,而字符串"([)]"和"{]"都不是有效的括号。

传统方法:使用栈

解决这道题的传统方法是使用栈,一种先进后出的数据结构。栈可以用来存储括号。当我们遍历字符串时,遇到左括号就将其压入栈中,遇到右括号就从栈中弹出与之匹配的左括号。如果遍历结束后栈中没有剩余的元素,则说明括号是有效的。

优化算法:Map助力匹配

但是,这种方法存在一个问题:它需要额外的空间来存储栈。为了优化算法,我们可以使用Map数据结构来代替栈。Map是一种键值对的数据结构,可以用来存储括号之间的匹配关系。

具体来说,我们可以将左括号作为键,将与之匹配的右括号作为值,存储在Map中。当我们遍历字符串时,遇到左括号就将其作为键添加到Map中,遇到右括号就将其作为值添加到Map中。如果在Map中找不到与之匹配的左括号,则说明括号无效。

这种方法不需要额外的空间来存储栈,而且查找速度更快。因此,它可以大大提高算法的效率。

代码实现

/**
 * 判断给定字符串中的括号是否有效
 *
 * @param {string} str 输入字符串
 * @return {boolean} 是否有效
 */
const isValid = (str) => {
  if (str.length % 2 !== 0) {
    return false;
  }

  const map = new Map();
  map.set('(', ')');
  map.set('{', '}');
  map.set('[', ']');

  const stack = [];

  for (let i = 0; i < str.length; i++) {
    const char = str[i];
    if (map.has(char)) {
      stack.push(char);
    } else if (stack.length > 0 && map.get(stack[stack.length - 1]) === char) {
      stack.pop();
    } else {
      return false;
    }
  }

  return stack.length === 0;
};

复杂度分析

  • 时间复杂度:O(n),其中n为字符串的长度。
  • 空间复杂度:O(n),其中n为字符串的长度。

常见问题解答

  1. 如何判断一个括号字符串是否有效?
    判断括号是否有效的方法是检查每个左括号是否都有一个匹配的右括号,并且每个右括号是否都有一个匹配的左括号。

  2. 什么情况下一个括号字符串是无效的?
    一个括号字符串在以下情况下是无效的:

    • 左括号比右括号多。
    • 右括号比左括号多。
    • 有一个右括号出现在左括号之前。
    • 有两个相同的左括号没有匹配的右括号。
    • 有两个相同的右括号没有匹配的左括号。
  3. 为什么Map比栈更适合用于括号匹配?
    Map比栈更适合用于括号匹配,因为它不需要额外的空间来存储栈,而且查找速度更快。

  4. 代码中的时间复杂度和空间复杂度分别是什么?
    代码的时间复杂度为O(n),其中n为字符串的长度。空间复杂度也为O(n),其中n为字符串的长度。

  5. 这道题在实际编程中有什么应用?
    这道题在实际编程中有很多应用,比如:

    • 验证代码是否有效。
    • 解析XML或JSON等格式化的数据。
    • 编写编译器或解释器。