首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >时间复杂度

时间复杂度

作者头像
西南_张家辉
发布2021-02-02 10:02:57
发布2021-02-02 10:02:57
60400
代码可运行
举报
文章被收录于专栏:张家辉的树屋张家辉的树屋
运行总次数:0
代码可运行

为了能在划水的时候找点事做

  • 准备刷下 leetcode
  • 重温一下时间复杂度的原理

时间复杂度

运行一次的基础代码要执行一次运算

代码语言:javascript
代码运行次数:0
运行
复制
const twice = (n)=>{
    console.log(" 运行一次 ");
    // 运行一次
    return;
    // 运行一次
}

/*
** 所以上面的代码执行了两次
*/

const multiple = (n)=>{
    for(let i = 0;i < n;i++){
        console.log("hello world")
    }
    // 运行 N 次
    return;
    // 运行一次
}

/*
** 上面的代码运行了 (n + 1) * 2 次
*/

复制代码

算法的时间复杂度推算

  • 可以看到我们的算法需要运算的次数,使用函数来表示,即 T(n)。
  • 我们为了估算算法的运行时间 和 简化算法分析,我们在这里引入时间复杂度的概念。

存在常数 c,使得当 N >= c 时 T(N) <= f(N),表示为 T(n) = O(f(n)) 。

  • 算法的时间复杂度,用来度量算法的运行时间,记作: T(n) = O(f(n))。它表示随着 输入大小n 的增大,算法执行需要的时间的增长速度可以用 f(n) 来描述。

我们现在已经有执行函数了T(n),我们得到算法的时间复杂度啦?

  • 1、们知道常数项对函数的增长速度影响并不大,所以当 T(n) = c,c 为一个常数的时候,我们说这个算法的时间复杂度为 O(1);如果 T(n) 不等于一个常数项时,直接将常数项省略。
代码语言:javascript
代码运行次数:0
运行
复制

比如第一个 Hello, World 的例子中 T(n) = 2,

所以我们说那个函数(算法)的时间复杂度为 O(1)。

T(n) = n + 29,此时时间复杂度为 O(n)。

  • 2、n^3 的增长速度是远超 n^2 的,同时 n^2 的增长速度是远超 n 的。 同时因为要求的精度不高,所以我们直接忽略低此项。
代码语言:javascript
代码运行次数:0
运行
复制
比如
T(n) = n^3 + n^2 + 29,此时时间复杂度为 O(n^3)。
  • 3、因为函数的阶数对函数的增长速度的影响是最显著的,所以我们忽略与最高阶相乘的常数。
代码语言:javascript
代码运行次数:0
运行
复制
比如
T(n) = 3n^3,此时时间复杂度为 O(n^3)。

综合起来:如果一个算法的执行次数是 T(n),那么只保留最高次项,同时忽略最高项的系数后得到函数 f(n),此时算法的时间复杂度就是 O(f(n))。为了方便描述,下文称此为 大O推导法。

四个遍历的法则

  • 1、对于一个循环,假设循环体的时间复杂度为 O(n),循环次数为 m,则这个 循环的时间复杂度为 O(n×m)。
代码语言:javascript
代码运行次数:0
运行
复制
const rateN = (n)=>{
    for(let i = 0; i < n;i ++){
        console.log("Hello,world!")
    }
}
复制代码

此时时间复杂度为 O(n * 1),即 O(n)

  • 2、对于多个循环,假设循环体的时间复杂度为 O(n),各个循环的循环次数分别是a, b, c...,则这个循环的时间复杂度为 O(n×a×b×c...)。分析的时候应该由里向外分析这些循环。
代码语言:javascript
代码运行次数:0
运行
复制
const rateMN = (n)=>{
    for(let i = 0; i < n;i ++){
        for(let j = 0; j < n; j++ ){
             console.log("Hello,world!")
        }
    }
}

复制代码

此时时间复杂度为 O(n × n × 1),即 O(n^2)。

  • 3、对于顺序执行的语句或者算法,总的时间复杂度等于其中最大的时间复杂度。
代码语言:javascript
代码运行次数:0
运行
复制
const complexOne = (n)=>{
    for(let i = 0; i < n;i ++){
        for(let j = 0; j < n; j++ ){
             console.log("Hello,world!")
        }
    }
    
    for(let i = 0; i < k;i ++){
        console.log("Hello,world!!!")
    }
}
复制代码

此时时间复杂度为 max(O(n^2), O(n)),即 O(n^2)。

  • 4、对于条件判断语句,总的时间复杂度等于其中 时间复杂度最大的路径 的时间复杂度。
代码语言:javascript
代码运行次数:0
运行
复制
const complexOne = (n)=>{
    if(n >= 0){
        
        for(let i = 0; i < n;i ++){
            for(let j = 0; j < n; j++ ){
                 console.log("Hello,world!")
            }
        }
    }else{
        for(let i = 0; i < k;i ++){
            console.log("Hello,world!!!")
        }
    }
}
复制代码

此时时间复杂度为 max(O(n^2), O(n)),即 O(n^2)。

综上所述,我们分析时间复杂度的基本策略是,从内而外,从深层次开始分析。如果遇到函数,需要深入函数进行分析

看一些简单的例子

一. 基础题 求该方法的时间复杂度

代码语言:javascript
代码运行次数:0
运行
复制
const aFunc(n) {
    for (let i = 0; i < n; i++) {
        for (let j = i; j < n; j++) {
            console.log("Hello World\n");
        }
    }
}

参考答案: 当 i = 0 时,内循环执行 n 次运算,当 i = 1 时,内循环执行 n - 1 次运算……当 i = n - 1 时,内循环执行 1 次运算。 所以,执行次数 T(n) = n + (n - 1) + (n - 2)……+ 1 = n(n + 1) / 2 = n^2 / 2 + n / 2。 根据上文说的 大O推导法 可以知道,此时时间复杂度为 O(n^2)。

二. 进阶题 求该方法的时间复杂度

代码语言:javascript
代码运行次数:0
运行
复制
const aFunc(n) {
    for (let i = 2; i < n; i++) {
        i *= 2;
        console.log("i:", i);
    }
}

参考答案: 假设循环次数为 t,则循环条件满足 2^t < n。 可以得出,执行次数t = log(2)(n),即 T(n) = log(2)(n),可见时间复杂度为 O(log(2)(n)),即 O(log n)。

三. 再次进阶 求该方法的时间复杂度

代码语言:javascript
代码运行次数:0
运行
复制
const aFunc(n) {
    if (n <= 1) {
        return 1;
    } else {
        return aFunc(n - 1) + aFunc(n - 2);
    }
}

参考答案: 显然运行次数,T(0) = T(1) = 1,同时 T(n) = T(n - 1) + T(n - 2) + 1,这里的 1 是其中的加法算一次执行。 显然 T(n) = T(n - 1) + T(n - 2) 是一个斐波那契数列,通过归纳证明法可以证明,当 n >= 1 时 T(n) < (5/3)^n,同时当 n > 4 时 T(n) >= (3/2)^n。

所以该方法的时间复杂度可以表示为 O((5/3)^n),简化后为 O(2^n)。 可见这个方法所需的运行时间是以指数的速度增长的。如果大家感兴趣,可以试下分别用 1,10,100 的输入大小来测试下算法的运行时间,相信大家会感受到时间复杂度的无穷魅力。

引用

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 时间复杂度
    • 运行一次的基础代码要执行一次运算
    • 算法的时间复杂度推算
    • 我们现在已经有执行函数了T(n),我们得到算法的时间复杂度啦?
    • 四个遍历的法则
    • 看一些简单的例子
    • 引用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档