算法与数据结构要点速学——时间复杂度(大 O)

时间复杂度 (大 O)

在这里插入图片描述
在这里插入图片描述
首先,我们来谈谈常用操作的时间复杂度,按数据结构/算法划分。然后,我们将讨论给定输入大小的合理复杂性。

数组(动态数组/列表)

规定 n = arr.length,

  • 在结尾添加或删除元素:O(1)
  • 从任意索引中添加或删除元素:O(n)
  • 访问或修改任意索引处的元素:O(1)
  • 检查元素是否存在:O(n)
  • 构建前缀和:O(n)
  • 求给定前缀和的子数组的和:O(1)

字符串 (不可变)

规定 n = s.length,

  • 添加或删除字符:O(n)
  • 任意索引处的访问元素:O(1)
  • 两个字符串之间的连接:O(n+m),其中 m 是另一个字符串的长度
  • 创建子字符串:O(m),其中 m 是子字符串的长度
  • 双指针:O(n*k),其中 k 是每次迭代所做的工作,包括滑动窗口
  • 通过连接数组、StringBuilder 等构建字符串:O(n)

链表

给定 n 作为链表中的节点数,

  • 给定指针位置的后面添加或删除元素:O(1)
  • 如果是双向链表,给定指针位置添加或删除元素:O(1)
  • 在没有指针的任意位置添加或删除元素:O(n)
  • 无指针任意位置的访问元素:O(n)
  • 检查元素是否存在:O(n)
  • 在位置 i 和 j 之间反转:O(j-i)
  • 使用快慢指针或哈希映射完成一次遍历:O(n)

哈希表/字典

给定 n = dic.length,

  • 添加或删除键值对:O(1)
  • 检查 key 是否存在:O(1)
  • 检查值是否存在:O(n)
  • 访问或修改与 key 相关的值:O(1)
  • 遍历所有键值:O(n)

注意,O(1) 操作相对于 n 是常数。然而,实际上哈希算法可能代价很高。例如,如果键是字符串,那么它将花费 O(m) 的时间,其中 m是字符串的长度。这些操作只需要相对于哈希映射大小的常数时间。

集合

给定 n = set.length,

  • 添加或删除元素:O(1)
  • 检测元素是否存在:O(1)

栈操作依赖于它们的实现。栈只需要支持弹出和推入。如果使用动态数组实现:

给定 n = stack.length,

  • 推入元素:O(1)
  • 弹出元素:O(1)
  • 查看(查看栈顶元素):O(1)
  • 访问或修改任意索引处的元素:O(1)
  • 检测元素是否存在:O(n)

队列

队列操作依赖于它们的实现。队列只需要支持出队列和入队列。如果使用双链表实现:

给定 n = queue.length,

  • 入队的元素:O(1)
  • 出队的元素:O(1)
  • 查看(查看队列前面的元素):O(1)
  • 访问或修改任意索引处的元素:O(n)
  • 检查元素是否存在:O(n)

注意:大多数编程语言实现队列的方式比简单的双链表更复杂。根据实现的不同,通过索引访问元素可能比 O(n) 快,但有一个重要的常量除数。

二叉树问题 (DFS/BFS)

给定 n 作为树的节点数,

大多数算法的时间复杂度为 O(n*k),其中 k 是在每个节点上做的操作数,通常是 O(1)。这只是一个普遍规律,并非总是如此。我们在这里假设 BFS 是用高效队列实现的。

二叉搜索树

给定 n 作为树中的节点数,

  • 添加或删除元素:最坏的情况下:O(n),平均情况:O(log n)
  • 检查元素是否存在:最坏的情况下:O(n),平均情况:O(log n)

平均情况是当树很平衡时,即每个深度都接近满。最坏的情况是树只是一条直线。

堆/优先队列

给定 n = heap.length 并讨论最小堆,

  • 添加一个元素:O(log n)
  • 删除最小的元素:O(log n)
  • 找到最小的元素:O(1)
  • 查看元素是否存在:O(n)

二分查找

在最坏的情况下,二分查找的时间复杂度为 O(log n),其中 n 是初始搜索空间的大小。

其他

  • 排序:O(n*log n),其中 n 是要排序的数据的大小
  • 图上的 DFS 和 BFS:O(n*k+e),其中 n 是节点数,e是边数,前提是每个节点处理花费都是 O(1),不需要重复遍历。
  • DFS 和 BFS 空间复杂度通常为 O(n),但如果它在图形中,则可能为
  • O(n+e) 来存储图形 动态规划时间复杂度:O(n*k),其中 n 是状态数,k 是每个状态所需要的操作数
  • 动态规划空间复杂度:O(n),其中 n 是状态数
  • 39
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SmiledrinkCat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值