练习内容
完成了以下练习:
栈的运用思想总结复盘
一、栈的本质
定义: 后进先出(LIFO)
核心作用:
处理「当前无法确定,需要等待后续信息」的问题
比如说
- 字符串解码:当右括号没出现时,无法确定需要重复的字符串内容。
- 每日温度:当大于自身温度的天数没出现时,答案天数是无法确定的。
而栈的作用就是存储住这些无法确定的数据,等待满足条件的元素出现时, 批量处理前面未解决的元素。(这也是相较于两次遍历的优势,将原本 O(n²) 的两层遍历,优化为 O(n))
什么时候考虑用栈
| 场景 | 关键词 | 用栈原因 |
|---|---|---|
| 括号匹配 | 成对 | 最近的先匹配 |
| 单调栈 | 找下一个更大/更小 | 批量结算 |
| 嵌套结构 | 一层套一层 | 作用域隔离 |
| 撤销操作 | undo | 后进先出 |
| 路径搜索 | 回退 | 记录路径 |
单调栈核心模型
for (let i = 0; i < len; i++) {
while (stack.length && arr[i] > arr[stack[stack.length - 1]]) {
let top = stack.pop();
//处理 top
}
stack.push(i);
}
具体思路
括号匹配
先定义一个栈
然后i遍历len
当遇到左括号的时候,将对应的右括号入栈
当不再是左括号的时候。就将右括号和栈顶元素比较
判断如果相等,就继续。不相等返回错误
并且最后匹配完时栈的长度应恰好是零,否则括号数量不匹配
所以最终应该return !stack.length
最小栈
借用一个辅助栈 min_stack,用于存获取 stack 中最小值。
push操作时具体就是单调栈的思想
需要注意的是在pop的时候如果出栈的元素等于最小值,需要 min_stack 也pop更新最小值
自己还有个失误:在 构造函数 内没挂this。
var MinStack = function() {
const stack = [];
const stack2 = [];
};
👉 这两个变量就是局部变量,构造函数执行完就没了
结果就是:this.stack 是 undefined
正确:
var MinStack = function() {
this.stack = [];
this.stack2 = [];
};
每日温度
初始化一个res数组 Array(len).fill(0),创建stack
递减栈思想→(栈空 || 温度小于栈顶)时push入栈,❗此时入栈的数据是Temperature[ ] 对应的index
当大于的时候,通过 while 循环批量弹出并处理:
var dailyTemperatures = function(temperatures) {
let stack = [];
let len = temperatures.length;
let res = Array(len).fill(0);
for (let i = 0; i < len; i++) {
while (stack.length && temperatures[i] > temperatures[stack[stack.length - 1]]) {
let top = stack.pop();
res[top] = i - top;
}
stack.push(i);
}
return res;
};
字符串解码
对称匹配+递归
啊啊啊看解说吧
作者:灵茶山艾府