持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
时间复杂度
-
算法中基本操作重复执行的次数
-
常见时间复杂度例子
时间复杂度 O(1) O(logn) O(n) O(n^2) 语句 赋值 二分搜索 for循环;while循环嵌套 for循环;嵌套while循环
空间复杂度
-
算法在运行过程中临时占用存储空间的大小
-
常见空间复杂度例子
空间复杂度 O(1) O(n) O(n^2) 语句 创建单一的变量 定义一个长度为 n的数组;长度为n的set/map;用for循环生成一个长度为n的链表二维/一维数组,每个元素存放一个长度为 n的set/map/链表
栈
JavaScript中没有栈,但可以用Array来实现栈的所有功能
-
栈的操作
-
入栈:
stack.push()->从尾部添加 -
出栈:
stack.pop()->从尾部删除 -
栈顶元素:
stack[stack.length-1]
-
-
栈的使用场景:后进先出
-
十进制转二进制:后得到的余数需要排到前面
-
有效的括号:左括号越靠前,对应的右括号越靠后
-
函数调用堆/栈:最后调用的函数最先执行完
-
-
典型力扣题
-
- 有效括号
-
队列
JavaScript中没有队列,但可以用Array来实现队列的所有功能
-
队列的操作
-
入队:
quene.push()=>从尾部添加 -
出队:
quene.shift()=>从头部删除 -
队头元素:
quene[0]
-
-
栈的使用场景:先进先出
-
典型力扣题
-
- 计算最近请求次数
-
-
前端中的队列👉事件循环中的任务队列
链表
JavaScript中没有链表,但是可以使用一系列Object来生成链表
-
链表的操作
- 定义
const a = { val: 'aaa' } const b = { val: 'bbb' } const c = { val: 'ccc' } const d = { val: 'ddd' } a.next = b b.next = c c.next = d- 遍历
let p = a while (p) { console.log(p.val) p = p.next }- 插入
//在c和d之间插入e const e = { val: 'e'} c.next = e e.next = d- 删除
//删除e //1. c已知 c.next = d //2. c未知 e.val = e.next.val e.next = e.next.next -
典型力扣题
-
- 两数相加:遍历链表、取余
-
- 删除排序链表中的重复元素:遍历链表、删除链表
-
- 判断环形链表:遍历链表、快慢指针
-
- 反转链表:遍历链表、双指针
-
- 删除链表中的节点
-
-
前端中的链表
-
原型链
-
遍历
JSON
-
集合
ES6中有集合,名为Set。类似于数组,但是没有重复的值
-
集合的常用操作
-
增添
add,删除delete -
判断元素是否在集合中
has -
遍历集合
for...of... -
集合和数组的相互转换
-
求交集和差集
-
-
典型力扣题
-
- 两个数组的交集
-
字典
ES6中有字典,名为Map。类似于Object,是键值对的集合
-
字典的常用操作
-
增
set -
删
delete, clear -
改
set, -
查
has(键),get(值)
-
-
典型力扣题
-
- 两数之和
-
- 无重复字符的最长字串
-
- 有效括号:只是用字典降低空间复杂度
-
- 最小覆盖字串
-
- 两个数组的交集
-
树
JavaScript中没有树,但是可以用Object和Array来构建:整个树是个对象,每个节点是一个对象,除根节点外所有节点都是数组的元素
-
树的常用操作
-
深度优先遍历:尽可能深的遍历树的分支
-
访问根节点
-
对根节点的children挨个进行深度优先遍历
-
-
广度优先遍历:先访问离根节点最近的节点
-
新建一个队列,把根节点入队
-
队头出队并访问
-
把对头的children挨个入队
-
重复第2和3步,直到队列为空
-
-
二叉树
JavaScript中用Object来构建二叉树
-
二叉树的常用操作
-
递归版
-
前序遍历:中左右
- 访问“根节点”
- 对“根节点”的左子树进行前序遍历
- 对“根节点”的右子树进行前序遍历
-
中序遍历:左中右
- 对“根节点”的左子树进行中序遍历
- 访问“根节点”
- 对“根节点”的右子树进行中序遍历
-
后序遍历:左右中
- 对“根节点”的左子树进行后序遍历
- 对“根节点”的右子树进行后序遍历
- 访问“根节点
-
-
非递归版
使用栈模拟函数的递归调用
-