算法合集 | 栈与队列 | Leetcode 20. 有效的括号

166 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第22天,点击查看活动详情

前言

本系列文章主要会总结一些常见的算法题目以及算法的易错点,难点,以及一些万用的公式,并且结合实际的 Leetcode 题目来进行加深理解以及实际应用,算法这种东西,属于是一到用时方恨少的类型,在平时总结一些常见的简单算法,经常磨练自己的算法思维,对于日常的开发还是能有不少的帮助的。

  • 今天还是来看一下栈与队列相关的知识以及题目

1. 什么是栈

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

栈其实就是一种数据结构 - 先进后出(先入栈的数据后出来,最先入栈的数据会被压入栈底)

image.png

2.栈的实现

前面我们说过,栈是一个线性表。所以,任何实现表的方法都可以用来实现栈

主要有两种方式:

链表实现栈

数组实现栈

假设用数组进行实现,就是利用数组的 push 和 pop 方法来模拟栈的入栈和出栈,数组的最后一个元素也就代表了栈顶的元素,第一个元素代表了栈底的元素。

Leetcode 20. 有效的括号

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

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

示例 1:

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

示例 2:

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

解题

括号匹配,是非常经典的利用栈解决的问题。

根据栈的特性,我们将碰到的括号一个个的推入栈中,一旦栈顶的元素和刚要入栈的元素是一对匹配的元素,那么就将栈顶移除,等同于两个相符合的括号就会相互抵消,都一起移除,下面用 ({})[] 来举一个例子

图片.png

首先将数组的括号一个个移入栈,直到第三个括号

图片.png

这时候会发现第三个括号和栈顶元素相匹配,那么就需要移除栈顶和要入栈的元素

图片.png

然后会发现栈内栈顶的元素因为上一个的移除变成了 ( 刚好又和下一个相对应,那么在此移除,栈内就为空剩余一个 []

图片.png

然后剩下的就没什么好说的,两个中括号也能够进行消除,整个栈就变成了空的,这时候就说明了是可以匹配的。

function isValid(s: string): boolean {
    let stack: string[] = [];
    for (let i = 0; i < s.length; i++) {
        switch (s[i]) {
            case '(':
                stack.push(')');
                break;
            case '[':
                stack.push(']');
                break;
            case '{':
                stack.push('}');
                break;
            default:
                if (stack.pop() !== s[i]) return false;
                break;
        }
    }
    return stack.length === 0;
};

图片.png