• ③ 数据结构之“栈”


    一、 理论

    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('')
    }
    
  • 相关阅读:
    Visual Studio DSL 入门 11为状态机设计器添加规则
    不平静的2009,期待更不平静的2010
    ASP.NET MVC 2 正式发布
    [翻译] DSL和模型驱动开发的最佳实践(2/4)
    Visual Studio DSL 入门 9创建状态机的图形符号
    Visual Studio DSL 入门 6DSL的图形表示1
    智诚B2C1.31正式发
    一个程序员的创业尝试
    Visual Studio DSL 入门 13结合T4生成代码
    Visual Studio DSL 入门 10完善状态机案例
  • 原文地址:https://www.cnblogs.com/pleaseAnswer/p/15816482.html
Copyright © 2020-2023  润新知