算法复杂度计算

发布于 2024-01-25 12:30:10 字数 3536 浏览 17 评论 0

在 LeetCode 上刷题,碰到一个题目,涉及时间复杂度的概念,如下。为了了解 O(n) 这个概念,后面去学习了时间复杂度相关内容。

76. 最小覆盖子串
给你一个字符串 S、一个字符串 T。请你设计一种算法,可以在 O(n) 的时间复杂度内,从字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:输入:S = "ADOBECODEBANC", T = "ABC“
输出:"BANC"

提示:如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

概念

首先算法复杂度是衡量算法好坏的一个重要指标。其次对算法的分析是通过预估分析得到,而不是将以该算法编写的程序上机运行,统计程序运行时间。

程序执行时间受运行环境和输入规模的影响,代码绝对执行时间无法估计。有时候这种统计甚至会掩盖算法本身的优劣。算法时间复杂度采用预估分析方法!

预估分析法

比较同一个问题的不同算法,通常的做法是,从算法中选取一种对于所研究的问题(或算法类型)来说是基本操作的原操作,以该基本操作的重复执行的次数作为算法的时间量度。

非精确计算出算法的运行时间,而是用统计方法分析出不同算法的花费时间长短。

主要分析代码的基本操作的执行次数。而算法花费时间与代码基本操作执行次数成正比。

T(n) 与 O(n)

(1)时间频度:一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为 T(n)。

(2)n 的含义:n 被称为问题的规模,当 n 变化时,T(n) 也不断变化。当我们想了解 T(n) 与 n 之间的变化规律时,此时引入一个新的概念——时间复杂度。

(3)时间复杂度:算法中基本操作重复执行的次数是问题规模 n 的某个函数,用 T(n) 表示,若有某个辅助函数 f(n),使得当 n 趋近于无穷大时,T(n)/f(n) 的极限值为不等于零的常数,则称 f(n) 是 T(n) 的同数量级函数。记作 T(n)=O(f(n))而称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度,用大写 O 表示。

推导 O(n)

分析 T(n)

分析由算法编写得到的代码可参考几个原则

  • O(1):适用输入输出语句、赋值语句、判断 if/else 语句、选择结构
  • 求和法则:适用常规语句,顺序结构

    T1(n)=O(f(n)) 和 T2(n)=O(g(n)),则 T1(n)+T2(n)=O(max(f(n), g(n)))
    T1(m)=O(f(m)), T2(n)=O(g(n)),则 T1(m)+T2(n)=O(f(m) + g(n))

  • 乘法法则:适用循环结构

    T1(n)=O(f(n)) 和 T2(n)=O(g(n)),则 T1T2=O(f(n)g(n))

  • 复杂算法可分解成比较容易估算的几个部分。

以下列举了一些实例

# O(1)
# 注意:如果算法的执行时间不随着问题规模 n 的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是 O(1)。
a='O1'
print(a)

# O(n)
# python 代码中对 list、set、str 等类型数据的部分操作为 O(n)
i=0
while i<n:
i+=1

# O(log2n),以 2 为底数的对数
i=1
while i<n:
i=i*2

n = 64
while n > 1:
print(n)
n = n // 2 # 循环减半

# O(n^2),双重嵌套循环,同理 O(n^3)
i=0; zzz
while i<n:
for j in list1: # 执行 n^2 次
val = list1[i]+j # 执行 n^2 次
i+=1

注意

Python 语法中对列表、集合、字符串、字典的部分操作时间复杂度为 $O(n)$。具体可 点击

循环减半则时间复杂度降为 $log2n$,代码如下:

n = 64
while n>1:
print(n)
n = n//2

推导 O((fn))

根据前面的概念。T(n)=O(f(n)),而 O(f(n)) 为时间复杂度。可以根据 T(n) 推导出 O(n)

推导时间复杂度 O(f(n)),有如下几个原则:

  • 如果运行时间是常数量级,用常数 1 表示;
  • 只保留时间函数中的最高阶项;
  • 如果最高阶项存在,则省去最高阶项前面的系数。

具体看几个实例规则:

1、$T(n) = 3n$,则 $T(n)=O(n)$; 时间复杂度 $O(n)$

2、$T(n) = 3$,则 $T(n)=O(1)$; 时间复杂度 $O(1)$

3、$T(n) = 5log_2n$ ,则 $T(n)=O(log_2n)$;时间复杂度 $O(log_2n)$

4、$T(n) = 3n^2$,则 $T(n)=O(n^2)$; 时间复杂度 $O(n^2)$

$$O(2n^2+n+1) = O(3n^2+n+3) = O(7n^2+n) = O(n^2)$$

总结

常见时间复杂度

常数阶 $Ο(1)$、 对数阶 $Ο(log_2n)$、线性阶 $O(n)$、 线性对数阶 $O(nlog_2n)$、平方阶 $O(n^2)$,立方阶 $O(n^3)$、…, k 次方阶 $O(n^k)$,指数阶 $O(2^n)$。随着问题规模 n 的不断增大,上述时间复杂度不断增大,算法的执行效率越低。

经验规则

$Ο(1)<Ο(log_2n)<Ο(n)<Ο(nlog_2n)<Ο(n^2)<Ο(n^3)<…<Ο(2^n)<Ο(n!)$
如果一个算法的复杂度为$c$ 、 $log_2n$ 、$n$、$nlog_2n$,那么这个算法时间效率比较高,如果是 $2^n$ 、$3^n$ 、$n!$,那么稍微大一些的 $n$ 就会令这个算法不能动了,居于中间的几个则差强人意。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

二手情话

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

我们的影子

文章 0 评论 0

素年丶

文章 0 评论 0

南笙

文章 0 评论 0

18215568913

文章 0 评论 0

qq_xk7Ean

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文