前端算法小白攻略23-leetcode(有效的括号)

200 阅读3分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战

前言

来了来了,它来了,经常会被问到的一个经典题型,判断给定的括号字符串是不是有效的,我们的括号字符串当然是只包含()[]{}这三种括号啦,同样,今天还是栈的话题,不过会提供两种解题思路哟。

题目描述

20. 有效的括号

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

有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/va… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

  1. 什么样的括号字符串为有效?什么又为无效?
    例如:"()"、"()[]{}"、"{[]}"这样的是有效,"(]"、"([)]"这样又交叉的视为无效
  2. 巧妙利用栈结构
    如果我们让括号字符按顺序入栈,遇到成对的有效括号就让它们出栈,到最后会留下一个空栈,如果括号字符串是无效的,那么肯定有没配对成功的留在栈里
  3. 配对协助工具
    你可以直接暴力if...else,也可以用switch...case,当然也可以搭配Es6新出的集合类型,利用它的键值对存储机制。
  4. 配对规则
    1)首先我们需要遍历括号字符串的括号字符,那么直接用for...of即可;
    2)如果是左括号'('、'['、'{',直接执行入栈操作;
    3)如果是右括号且栈内没有元素了,那说明前面没有能与该右括号配对的的左括号了,说明当前是无效括号字符串,返回false;
    4)如果是右括号且栈内有元素,还需判断栈顶元素是否能与当前右括号配对,如果没有能配对的,则说明不同类型的括号交叉了,说明当前是无效括号字符串,返回false; 5) 如果是右括号且能成功配对,那就让栈顶能配对的元素出栈即可; 6)最后如果栈为空则说明该括号字符串有效,否则,无效。

开始解题

1、用switch...case + 栈


var isValid = function(s) {
    let stack = [];
    for(char of s) {
        switch(char) { // 遇到右括号,if判断中直接判断栈顶pop元素是否能达成同类型括号配对,
            case ')':  // 包含了空栈的情况,也是无效配对,不能就返回false说明当前不是有效括号字符串
                if(stack.pop() !== '(') return false;
                break;
            case ']':
                if(stack.pop() !== '[') return false;
                break;
            case '}':
                if(stack.pop() !== '{') return false;
                break;
            default: // 默认情况是遇到左括号的条件直接入栈
                stack.push(char);
        }
    }
    return !stack.length;
};

2、用Map + 栈

    let map = new Map([ // 使用嵌套数组,右括号为键,左括号为值的键值对方式初始化Map映射
        [')','('],
        [']','['],
        ['}','{'],
    ])
    let stack = [];
    for(char of s) {
        if(map.has(char)) { // 如果当前括号字符能匹配上以右括号为键的Map映射时
            if(!stack.length || stack[stack.length-1] !== map.get(char)){ 
                return false; // 栈为空或栈顶元素不能完成配对说明当前是无效括号字符串
            }
            stack.pop();
        }else {            // else的情况就是遇到左括号即入栈
            stack.push(char);
        }
    }
    return !stack.length;
};