③ 数据结构之“栈”

一、 理论

1. 栈简介

  • 一个 先进后出 的数据结构
  • js中没有栈,但可以用Array实现队列的所有功能
// stack
const stack = []
stack.push(1)
stack.push(2)
const item1 = stack.pop()
const item2 = stack.pop()

2. 栈的应用场景

  • 需要 后进先出 的场景

2.1 十进制转二进制

  • 后出来的余数反而排在前面
  • 把余数一次入栈,再出栈

2.2 有效的括号

((((()))))   -- valid
()()()()     -- valid
((((((()     -- invalid
((()(())))   -- valid
  • 越靠后的左括号,对应的右括号越靠前
  • 左括号入栈、右括号出栈,最后栈空了就是合法的

2.3 函数调用堆栈

function greeting() {
  sayHi()
}
function sayHi() {
  return 'Hi!'
}
greeting()
  • 最后调用的函数最先执行完
  • js解释器使用栈来控制函数的调用顺序

二、刷题

1. 有效的括号(20)

1.1 题目描述

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

1.2 解题思路

  • 越靠后的左括号,对应的右括号越靠前

1.3 解题步骤

  • 新建栈
  • 扫描字符串
    • 遇到左括号就入栈
    • 遇到和栈顶匹配的右括号则出栈
      • 不匹配则false
      • 最后栈空true
function isValid(s) {
  if(s.length % 2 == 1) return false
  const stack = []
  for(let i = 0; i < s.length; i++) {
    let c = s[i]
    if(c == '(' || c == '{' || c == '[') {
      stack.push(c)
    } else {
      const t = stack[stack.length-1]
      if(
        (t == '(' && c == ')') ||
        (t == '{' && c == '}') ||
        (t == '[' && c == ']')
      ) {
        stack.pop()
      } else {
        return false
      }
    }
  }
  return stack.length == 0
}

1.4 时间复杂度&空间复杂度

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

2. 函数调用堆栈(前端与栈)

code part

// callStack
const func1 = () => {
  func2()
}
const func2 = () => {
  func3()
}
const func3 = () => {}
func1()

3. 二叉树的前序遍历(144)

使用栈模拟递归、改写递归

3.1 题目描述

  • 给你二叉树的根节点 root ,返回它节点值的 前序 遍历

1.2 解题

function preorderTraversal(root) {
  const res = []
  const stack = []
  if(root) stack.push(root)
  while(stack.length) {
    const n = stack.pop()
    res.push(n.val)
    if(n.right) stack.push(n.right)
    if(n.left) stack.push(n.left)
  }
  return res
}

1.4 时间复杂度&空间复杂度

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

三、总结 -- 技术要点

  • 栈是一个后进先出的数据结构
  • js中没有栈,但可以用Array实现栈的所有功能
  • 栈的常用操作:push pop stack[stack.length-1]

四、思考题

1. 实现栈类

class Stack {
  constructor() {
    this.stack = []
  }
  push(c) {
    this.stack.push(c)
  }
  pop() {
    return this.stack.pop()
  }
  peek() {
    return this.stack[this.stack.length-1]
  }
}

2. 实现ten2Two函数

function ten2Two(num) {
  const stack = []
  while(num) {
    stack.push(num % 2)
    num = parseInt(num/2)
  }
  return stack.reverse().join('')
}
posted on 2022-01-18 09:55  pleaseAnswer  阅读(20)  评论(0编辑  收藏  举报