手摸手提桶跑路——LeetCode20. 有效的括号

132 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情

题目描述

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

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

示例 1:

输入:s = "()"
输出:true

示例 2:

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

示例 3:

输入:s = "(]"
输出:false

示例 4:

输入:s = "([)]"
输出:false

解题思路——抵消法

首先通过题目我们可以知道,如果给定的字符串是有效的,那么括号一定是成对存在的,每个类型的左括号对应一个各自类型的右括号,没有一个多余或缺少的。

拿字符串 ()[]{} 来说,我们可以先消除 (),然后消除 [],最后消除 {},最后字符串剩下了 "",消除的先后顺序不重要,只要能消完就说明字符串中各个类型的括号都是配对的。

那么我们就可以通过循环,不断消除各个类型的括号,直到 全部消除完剩下几个单身括号

我们都知道如果能消完的话,一次能消除两个括号,且最后剩余的是空字符串。那么对于一个长度为 n 的字符串 s,我们需要的循环次数为 n / 2,如果剩余字符串不是空串,说明不能两两配对完,否则说明该字符串是有效的。

题解

/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
    let cnt = s.length >> 1;

    while(cnt--) {
        if(s.includes('()')) {
            s = s.replace('()', '');
        } else if(s.includes('[]')) {
            s = s.replace('[]', '');
        } else if(s.includes('{}')) {
            s = s.replace('{}','');
        }
    }
    return s.length === 0;
};

微信截图_20220824231252.png

解题思路——栈

相信大家都知道栈的特性了,就是后进先出。那么栈和今天的题目有什么关系呢?

本题只有在 左括号与同类型的右括号相遇 的时候,才能将这两个括号抵消,所以我们可以将所有未被抵消的括号都 存在一个栈 中,一旦当前遍历到的元素和栈顶的元素是 配对 的,那么就可以消除栈顶的元素,这么遍历到最后的话,如果字符串中的每个字符都是配对的,那么最后抵消完的字符串就是有效的(空串),否则就说明该字符串是无效的(非空串)。

题解

var isValid = function(s) {
    const stack = [], mp = {
        ')': '(',
        ']': '[',
        '}': '{'
    };

    for(let o of s) {
        if(stack.length && stack[stack.length - 1] === mp[o]) { // 遇到结束符号
            stack.pop();
            continue;
        }
        stack.push(o);
    }

    return stack.length === 0;
};

微信截图_20220824230938.png