(初学Map,执行用时击败93.31%用户)20.有效的括号

190 阅读2分钟

题面

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

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 注意空字符串可被认为是有效字符串。

示例

示例 1:

  • 输入: "()"
  • 输出: true

示例 2:

  • 输入: "()[]{}"
  • 输出: true

示例 3:

  • 输入: "(]"
  • 输出: false

示例 4:

  • 输入: "([)]"
  • 输出: false

示例 5:

  • 输入: "{[]}"
  • 输出: true

解题思路

  1. 先判断字符串长度是否为偶数,不是偶数的话,可以直接返回false
  2. 由题可知:是两个元素的对应关系,因此可以用哈希映射来解决,那么此时就可以使用Map
  3. 分析可知:遇到的左括号压入栈顶,遇到右括号将栈中的左括号弹出来进行匹配。 匹配不成功:false 匹配成功:进入下一轮
  4. 直到整个字符串被比较完成,判断当前堆是否为空 非空:false 空:true

解题源码

  • 首次源码
/**
 * @param {string} s
 * @return {boolean}
 */
/* 几种情况:
   1. 左括号单身
   2. 右括号单身
*/
var isValid = function (s) {
    // 创建线性表,模仿栈
       // 取出字符串开头判断是:左括号 还是 右括号
          // 1.左括号:继续往里面找,直到找到最里面的左括号,同时将左括号压入栈顶
          // 找到第一个右括号,弹出最里面的一个左括号,查看是否匹配
               // 不匹配 false
               // 匹配 true
                   // 如果 字符串还有右括号 ,此时栈里没有左括号 -> 右括号单身 false
                   // 如果 栈 还有左括号,此时字符串中没有 -> 左括号单身 false
          // 2.右括号:false
    /* 
       又可以改进的地方:长度为奇数的时候,直接返回false
     */
    length = s.length;
    if(length % 2 != 0){  // 优化
        return false;
    }

    // 哈希映射
    //声明一个map集合
    var myMap = new Map([
        [')','('],
        ['}','{'],
        [']','[']
    ]);

    // 定义一个栈: 栈相当于特殊的链表
    var stk = [];

    var rightKH = s.charAt(0);
    // 对于string可以使用charAt()函数来获取当前的值
    for(var i = 0; i < length; i++){
        rightKH = s.charAt(i);
        //如果是 左括号 一直找下去
        if(rightKH == "(" || rightKH == "{" || rightKH == "["){
            //将左括号 放入栈中
            stk.push(rightKH);
        }else {
            var value = stk.pop();
            // 当前为右括号 判断是否有与之相符的左括号
            if(rightKH == ")"){
                if(myMap.get(")") != value){
                    return false;
                }
            }else if(rightKH == "}"){
                if(myMap.get("}") != value){
                    return false;
                }
            }else if(rightKH == "]"){
                if(myMap.get("]") != value){
                    return false;
                }
            }
        }
    }
    if(stk.length != 0){
        return false;
    }
    return true;
};
/*
   查询补充:
     js中定义变量:const let var
     1. const 定义的变量不可修改,必须初始化
     2. let 定义的变量块级作用域,函数内部使用let定义后,对函数外部无影响
     3. var定义的变量可以修改,如果不初始化会输出undefined,不会报错
 */
  • 第二次源码
var isValid = function (s) {
    length = s.length;
    if(length % 2 != 0){
        return false;
    }

    // 哈希映射
    //声明一个map集合
    var myMap = new Map([
        [')','('],
        ['}','{'],
        [']','[']
    ]);

    // 定义一个栈: 栈相当于特殊的链表
    var stk = [];

    var rightKH = s.charAt(0);
    // 对于string可以使用charAt()函数来获取当前的值
    for(var i = 0; i < length; i++){
        rightKH = s.charAt(i);
        //如果是 左括号 一直找下去
        if(rightKH == "(" || rightKH == "{" || rightKH == "["){
            //将左括号 放入栈中
            stk.push(rightKH);
        }else {
            var value = stk.pop();
            // 当前为右括号 判断是否有与之相符的左括号
            // if(rightKH == ")"){
            //     if(myMap.get(")") != value){
            //         return false;
            //     }
            // }else if(rightKH == "}"){
            //     if(myMap.get("}") != value){
            //         return false;
            //     }
            // }else if(rightKH == "]"){
            //     if(myMap.get("]") != value){
            //         return false;
            //     }
            // }
            //将上述替换为下面语句
            if(myMap.get(rightKH) != value){
                // console.log(myMap.get(rightKH));
                return false;
            }
        }
    }
    if(stk.length != 0){
        return false;
    }
    return true;
};
  • 运行效率

注意

查询补充:js中定义变量:const let var

  • const 定义的变量不可修改,必须初始化
  • let 定义的变量块级作用域,函数内部使用let定义后,对函数外部无影响
  • var定义的变量可以修改,如果不初始化会输出undefined,不会报错

代码优化

// 两个匹配问题,那么字符串长度一定是偶数
  if(length % 2 != 0){  // 优化
        return false;
    }

代码出错点

// 判断栈是否为空
if(stk.length != 0){
   return false;
}
   return true;

学习Map

  • 声明方式
var myMap = new Map([
      [')','('],
      ['}','{'],
      [']','[']
  ]);
  • 通过key获取相应的value值
myMap.get(rightKH) -> value