开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第22天,点击查看活动详情
前言
本系列文章主要会总结一些常见的算法题目以及算法的易错点,难点,以及一些万用的公式,并且结合实际的 Leetcode 题目来进行加深理解以及实际应用,算法这种东西,属于是一到用时方恨少的类型,在平时总结一些常见的简单算法,经常磨练自己的算法思维,对于日常的开发还是能有不少的帮助的。
- 今天还是来看一下栈与队列相关的知识以及题目
栈
1. 什么是栈
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
栈其实就是一种数据结构 - 先进后出(先入栈的数据后出来,最先入栈的数据会被压入栈底)
2.栈的实现
前面我们说过,栈是一个线性表。所以,任何实现表的方法都可以用来实现栈。
主要有两种方式:
链表实现栈
数组实现栈
假设用数组进行实现,就是利用数组的 push 和 pop 方法来模拟栈的入栈和出栈,数组的最后一个元素也就代表了栈顶的元素,第一个元素代表了栈底的元素。
Leetcode 20. 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
解题
括号匹配,是非常经典的利用栈解决的问题。
根据栈的特性,我们将碰到的括号一个个的推入栈中,一旦栈顶的元素和刚要入栈的元素是一对匹配的元素,那么就将栈顶移除,等同于两个相符合的括号就会相互抵消,都一起移除,下面用 ({})[] 来举一个例子
首先将数组的括号一个个移入栈,直到第三个括号
这时候会发现第三个括号和栈顶元素相匹配,那么就需要移除栈顶和要入栈的元素
然后会发现栈内栈顶的元素因为上一个的移除变成了 ( 刚好又和下一个相对应,那么在此移除,栈内就为空剩余一个 []
然后剩下的就没什么好说的,两个中括号也能够进行消除,整个栈就变成了空的,这时候就说明了是可以匹配的。
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;
};