栈是一种后进先出(LIFO)的数据结构,在前端开发中有着广泛的应用。

栈 (Stack) 数据结构

栈是一种后进先出(LIFO - Last In First Out)的数据结构,只能在一端进行插入和删除操作。

// 栈的核心操作

class Stack<T> {
  private items: T[] = [];

  push(item: T): void    // 入栈
  pop(): T | undefined   // 出栈
  peek(): T | undefined  // 查看栈顶
  isEmpty(): boolean     // 是否为空
  size(): number         // 栈大小
}

前端常见应用场景:

  • 浏览器前进/后退历史
  • 撤销/重做功能 (Ctrl+Z / Ctrl+Y)
  • 函数调用栈
  • 括号匹配验证
  • 表达式求值
  • 深度优先搜索 (DFS)

示例 1: 栈的基本操作

← 栈顶 (Top)
空栈
栈底 (Bottom) →

栈大小: 0

是否为空:

示例 2: 括号匹配(经典算法题)

判断字符串中的括号是否有效匹配。支持 ()、[]、

function isValid(s: string): boolean {
  const stack: string[] = [];
  const pairs = { ')': '(', ']': '[', '}': '{' };

  for (const char of s) {
    if ('([{'.includes(char)) {
      stack.push(char);
    } else if (')]}'.includes(char)) {
      if (stack.pop() !== pairs[char]) {
        return false;
      }
    }
  }
  return stack.length === 0;
}

示例 3: 浏览器历史记录

浏览器的前进/后退功能就是用两个栈实现的!

当前页面:
首页
后退栈 (Back Stack):
前进栈 (Forward Stack):

示例 4: 函数调用栈可视化

function bar() {
  console.log('Hello');
}
function foo() {
  bar();
}
function main() {
  foo();
}
main();
调用栈 (Call Stack):
执行日志:
重要概念: JavaScript 是单线程语言,函数调用通过调用栈管理。 栈溢出(Stack Overflow)就是因为递归太深导致调用栈超出限制。

代码练习

在下面的编辑器中编写代码,点击"运行"按钮来测试你的解答。

有效的括号

简单

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合,左括号必须以正确的顺序闭合。

javascript
加载编辑器中...
1简单匹配
输入["()"]
期望true
2多种括号
输入["()[]{}"]
期望true
3嵌套括号
输入["({[]})"]
期望true
4不匹配
输入["(]"]
期望false
5顺序错误
输入["([)]"]
期望false
6空字符串
输入[""]
期望true
7只有左括号
输入["(("]
期望false

移除元素

简单

给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量 k。要求:更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。

javascript
加载编辑器中...
1基本测试

移除所有的 3,剩余 [2, 2]

输入[[3,2,2,3],3]
期望2
2多个目标值

移除所有的 2,剩余 5 个元素

输入[[0,1,2,2,3,0,4,2],2]
期望5
3空数组
输入[[],1]
期望0
4全部移除

所有元素都等于 val

输入[[1,1,1],1]
期望0
5无需移除

没有元素等于 val

输入[[1,2,3],4]
期望3
6单元素匹配
输入[[1],1]
期望0
7单元素不匹配
输入[[1],2]
期望1

最小栈

中等

设计一个支持 push、pop、top 和 getMin 操作的栈。getMin 操作应该在常数时间内返回栈中的最小元素。

javascript
加载编辑器中...
1基本操作

push -2, push 0, push -3, getMin, pop, top, getMin

输入[["push","push","push","getMin","pop","top","getMin"],[-2,0,-3,null,null,null,null]]
期望[null,null,null,-3,null,0,-2]
2相同最小值
输入[["push","push","push","getMin","pop","getMin"],[1,1,1,null,null,null]]
期望[null,null,null,1,null,1]