算法练习第12道-有效的括号

110 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

题目

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

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。 示例 1:
输入:s = "()"
输出:true
示例 2:

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

输入:s = "(]"
输出:false
示例 4:

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

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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re…

思路分析

  • 首先判断括号是一对一对的,length长度不能为奇数
  • 寻找下规律 { [ ( ) ] }
  • 满足条件下最内层必然是一个符合规则的括号,我们就把符合规则的符号过滤掉,
  • 得到的就是剩余不符合规则的括号或者空

代码

let isValid = function(s) {
  /**
   * 首先判断length长度不能为奇数
   * 寻找下规律 { [ ( ) ] }
   * 满足条件下最内层必然是一个符合规则的括号,我们就把符合规则的符号过滤掉,
   * 得到的就是剩余不符合规则的括号或者空
   * 
   * **/ 
  let n = s.length
  if(n%2 != 0) return false
  while(true) {
    let len = s.length
    s = s.replace('()', '')
    s = s.replace('[]', '')
    s = s.replace('{}', '')
    if(s.length == len) {
      return len == 0
    }
  }

}

测试结果

image.png

优化

思路

  • 示例 {{[()]}}
  • 我们真实比对的其实是右括号,按这个思路
  • 如果是{、(、[, 我们就直接push进数组中, 如果进来的是} ] ), 那么我们就要比较之前的push进数组的括号
  • 如果比对上,那么就删除右括号,如果没有比对上或者数组长度为空了,就直接返回false

代码

/**
   * 示例 {{[()]}} 
   * 我们真实比对的其实是右括号,按这个思路
   * 如果是{、(、[,  我们就直接push进数组中,如果进来的是} ] ), 那么我们就要比较之前的push进数组的括号
   * 如果比对上,那么就删除右括号,如果没有比对上或者数组长度为空了,就直接返回false
   * */ 
  let n = s.length
  if(n%2 != 0) return false
  const pairs = new Map([
      [')', '('],
      [']', '['],
      ['}', '{']
  ]);

  const stk = []
  for(let ch of s) {
    if(pairs.has(ch)) {
      if(!stk.length || stk[stk.length - 1] != pairs.get(ch)) {
        return false
      }
      stk.pop()
    } else {
      stk.push(ch)
    }
  }
  return !stk.length