【算法实战之力扣刷题】有效的括号

152 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

题目描述:

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

有效字符串需满足:

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

输入: s = "()"

输出: true

解题思路:

  1. 字符串为有效的括号,则长度一定是偶数

  2. 遍历字符串,遇到左括号就存储起来;遇到后面的右括号就检查是否可以与最后存储的左括号相匹配,如果可以匹配,就移除出去;遍历完所有括号,字符串就为空。这种思考过程就与栈数据结构先入后出的特点一致

新建画布1.jpg

  1. 因此准备一个栈存放括号对,遍历字符串的时候,遇到左括号就入栈,遇到右括号则判断右括号是否能和栈顶元素匹配,如果不匹配,直接return false(不是有效的括号),如果匹配,就把匹配的括号出栈

  2. 在循环结束的时候,判断栈是否为空,如果为空,则是有效括号,反之不是

/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
  const len = s.length;
  //字符串长度为奇数,直接返回
  if(len % 2 === 1) return false;
  const pairs = new Map([
    [')', '('], //因为需要判断字符串的右括号是否匹配左括号,因此需要右括号作为键值(key)
    [']', '['],
    ['}', '{']
  ])
  const stack = [] //创建一个栈
  for(let item of s){
    // 如果item为右括号,判断右括号是否能和栈顶元素匹配,反之,把左括号存入栈中
    if(pairs.has(item)){
        //如果右括号不能和栈顶元素匹配,直接返回;如果匹配,就把匹配的括号删除(相当于删除数组最后一个元素)
        if(!stack.length || stack[stack.length - 1] !== pairs.get(item)){
            return false;
        }
        stack.pop()
    }else{
        stack.push(item) //遇到左括号入栈
    }
  }
  return !stack.length;//循环结束的时候,判断栈是否为空
};

image.png

注:此题解法中关于map的相关知识可以阅读这一篇文章:【算法实战之力扣刷题】两数之和

扩展:for...of 循环

for...of循环是ES6的语法,可以遍历 Arrays(数组), Strings(字符串), 类似数组的对象(比如arguments对象、DOM 对象),可迭代的对象(Map(映射), Set(集合))

for...of循环,遍历获得键值(value);for...in循环,遍历获得键名(key)

const array = ['西瓜', '桃子', '樱桃'];
const string = '[{}]';

const map = new Map([
    ['one', 1], 
    ['two', 2]
]);

//遍历数组
for (let item of array) {
    console.log(item)
    // 西瓜
    // 桃子
    // 樱桃
}
for (let item in array) {
    console.log(item)
    // 0
    // 1
    // 2
}

//遍历字符串
for (let value of string) {
    console.log(value)
    // [
    // {
    // }
    // ]
}

//  遍历map
// 每次循环都会返回一个数组[key,value],使用解构表达式const [number,name]立即对这对数组进行解构。
for (const [name, number] of map) {
    console.log(name,number)
    // one 1
    // two 2
}

注:for…of循环不能循环普通的对象,推荐循环遍历普通对象的属性时使用for…in循环