探索栈数据结构:理解其原理与应用场景
前言
栈是一种常见的数据结构,它是一种具有特定行为的有序集合。栈的特点是后进先出(Last In, First Out,简称 LIFO),也就是最后放入的元素最先被取出。你可以将栈想象成一叠盘子,你每次放入一个盘子时,它就被放在其他盘子的顶部;而取出盘子时,也是从顶部开始取。
栈通常有两个基本操作:
- 压入(Push) :向栈中添加一个元素。这个元素被放置在栈的顶部。
- 弹出(Pop) :从栈中移除顶部的元素,并返回该元素。
栈和数组的区别:
正文
通过栈的一些基本操作来实现吃雪糕
代码
//栈
const stack = [];
stack.push('钟薛高');
stack.push('小布丁');
stack.push('绿舌头');
stack.push('可爱多');
while(stack.length) {
const top = stack.pop();
console.log('取出:',top);
}
大家有没有吃到雪糕呢?接下来让我们看看一些算法题吧~
实例一
题目:给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
测试s='([{}])':
解题思路:我们设计一个栈stack,遍历s,如果遍历到左边的括号,就把它对应的右括号通过push压入栈,如果遍历到右边的括号,就通过pop将栈的顶部元素出栈,并判断出栈的元素与该元素是否一致,如果不一致,则返回false,遍历结束全部一致就返回true。
怎么实现遍历到左边的括号,然后将右边的括号压入栈呢?
可以通过if判断语句来实现,但是这里我们介绍另一种方法
- 创建一个对象leftToRight:
const leftToRight = {
'(': ')',
'[': ']',
'{': '}'
};
- 先判断该对象中是否存在以该字符串为key的键值对,如果存在,则为左括号,并将该value压入栈,如果不存在(undefined)则为右括号,则出栈,并进行比对。
let stack = [];
for (let i = 0; i < s.length; i++) {
if(leftToRight[s[i]] !== undefined){
stack.push(leftToRight[s[i]]);
}
else{
res = stack.pop();
if(res !== s[i]){
return false;
}
}
}
return true;
该代码存在一个bug:
- 如果s='[',执行结果为true,因为根本没有右括号,此时栈中为[']'],遍历完,直接返回true。
改进
- 将
return true;
改成return !stack.length;
,因为如果完全匹配的话,最后栈应该为空的,所以对栈的长度取反,如果长度为0,则说明完全匹配,0为false,取反后为true,如果长度不为0,说明不完全匹配则为true,取反为true。 - 在执行上诉代码时先判断s的长度是否为偶数,因为长度为奇数肯定时不匹配的,就不用再去遍历s。
if(s.length % 2 !== 0){
return false;
}
stack的图解
结语
希望我的分享能给你带来帮助哟~一起加油,向前冲!
转载自:https://juejin.cn/post/7366826090836213799