算法随笔-数据结构(栈)
本文主要介绍数据结构中的栈的特点、使用场景、ES6实现Stack类和题解leetCode真题。供自己以后查漏补缺,也欢迎同道朋友交流学习。
引言
栈
这个名字对开发者来说不应该陌生,我们经常说调用栈、堆栈等术语,指的就是数据结构-栈
。栈是一种非常基础的数据结构,在计算机科学和软件开发的许多领域中都有广泛的应用。
栈(Stack
)是一种遵循后进先出
(LIFO
,Last In First Out)原则的数据结构。这意味着最后添加到栈中的元素将是第一个被移除的元素。栈的这个特性使得它在许多应用场景中非常有用,尤其是在处理数据的顺序和层次结构时。
栈的主要特点
- 限制性访问:只能在栈的顶部(称为栈顶)进行添加(push)和删除(pop)操作。
- 主要操作:
push
:向栈顶添加一个新元素。pop
:移除栈顶的元素,并返回它。peek
或top
:查看栈顶的元素,但不从栈中移除它。isEmpty
:检查栈是否为空。
- 容量:有些栈实现有固定的最大容量,而有些可以实现动态扩展。
- 时间效率:栈的基本操作(push、pop、peek)通常都是O(1)时间复杂度,即它们可以在常数时间内完成。
栈的应用场景
- 函数调用:编程语言中的函数调用通常使用
调用栈
来管理,每次函数调用时,相关信息(如返回地址和局部变量)被压入栈中,函数执行完毕后,这些信息被弹出。 - 撤销操作:许多应用程序(如文本编辑器)提供
撤销功能
,可以使用栈来存储操作历史
,以便可以回退到之前的状态。 - 解析表达式:栈用于解析和计算表达式,特别是后缀和前缀表达式。
- 深度优先搜索(DFS):在图的遍历中,
DFS
使用栈来存储待访问的节点。 - 括号匹配:检查代码中的括号是否正确匹配,可以使用栈来跟踪最近遇到的开括号。
- 回溯算法:在解决一些问题时(如
迷宫求解
、N皇后
问题等),回溯算法会用栈来存储中间状态。 - 数据结构辅助:栈可以作为其他数据结构(如队列的实现)的辅助结构使用。
- 内存管理:在一些低级编程中,栈可能会用于管理内存分配和回收。
栈是一种非常基础的数据结构,在计算机科学和软件开发的许多领域中都有广泛的应用。
ES6实现栈类
在 ES6
中,可以使用数组来实现栈的数据结构,因为数组本身具有类似栈的操作功能,如 push
用于添加元素到栈顶,pop
用于移除栈顶元素。以下是使用JavaScript数组实现栈的一个简单示例:
在这个Stack
类中,我们定义了以下方法:
push(element)
: 向栈中添加一个元素。pop()
: 移除并返回栈顶元素。如果栈为空,则抛出错误。peek()
: 返回栈顶元素但不移除它。如果栈为空,则抛出错误。isEmpty()
: 检查栈是否为空。size()
: 返回栈中元素的数量。clear()
: 清空栈中的所有元素。
LeetCode真题
1047. 删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:"abbaca"
输出:"ca"
解释: 例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
题解:
20. 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
示例1:
输入:s = "()"
输出:true
示例2:
输入:s = "()[]{}"
输出:true
示例3:
输入:s = "(]"
输出:false
题解: