计算时间复杂度

1.引言

我们之前学过许多算法,例如:二分查找归并排序(博客链接,若没学过,慢走不送)。

我们在学习二分查找的时候就抛出过一个问题:如何计算时间复杂度。我们当时只是粗略的讲了一下什么是时间复杂度,今天我们来学习计算一下。

2.计算时间复杂度

2.1 认识不同种类时间复杂度

2.1.1 常数阶

即时间复杂度为 的算法。例如:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    cout << "Hello World" << endl; // 运行第一步
    return 0;
}

但不一定只执行一次,又例如:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; // 运行第一步
    cin >> n; // 运行第二步
    cout << n << endl; // 运行第三步
    return 0;
}

这段代码的时间复杂度也是 O(1),只要没有循环(重复写一段代码也算循环)时间复杂度就是 O(1)

2.1.2 对数阶

即时间复杂度为 ******的算法,例如:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; // 执行1次
    cin >> n; // 执行1次
    int sum = 1; // 执行1次
    while(sum < n) // 执行 LogN 次
        sum *= 2; // 每次执行1次
    cout << sum << endl; // 执行1次
    return 0;
}

这里默认是 ,如果是以2为底,那么在 编程 中可以省略,数学中不可以。如果是以别的数字为底,那么需要特殊标注,例如

2.1.3 线性阶

即时间复杂度为 的算法,例如:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; // 执行1次
    cin >> n; // 执行1次
    for(int i = 1; i <= 10; i++) // 执行 n 次
        cout << i << " "; // 每次执行1次
    cout << endl; // 执行1次
    return 0;
}

我们可以看到,就是一个单纯的循环。

2.1.4 nlogn阶

即时间复杂度为 的算法。例如:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; // 执行1次
    cin >> n; // 执行1次
    for(int i = 1; i <= n; i++) // 执行 n 次
    {
        int sum = 1; // 每次执行1次
        while(sum < n) // 每次执行 LogN 次
            sum *= 2; // 每次执行1次
        cout << sum << endl; // 每次执行1次
    }
    return 0;
}

就是 特别简单。

2.1.5 平方阶

即时间复杂度为 的算法。例如:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; // 执行1次
    cin >> n; // 执行1次
    for(int i = 1; i <= n; i++) // 执行 n 次
    {
        for(int j = 1; j <= n; j++) // 每次执行 n 次
            cout << '(' << i << ', ' << j << ')' << ' '; // 每次执行1次
        cout << endl; // 每次执行1次
    }
    return 0;
}

就是 特别简单。

2.1.6 立方阶

即时间复杂度为 的算法。例如:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; // 执行1次
    cin >> n; // 执行1次
    for(int i = 1; i <= n; i++) // 执行 n 次
    {
        for(int j = 1; j <= n; j++) // 每次执行 n 次
        {
            for(int k = 1; k <= n; k++) // 每次执行 n 次
                cout << '(' << i << ', ' << j << ', ' << ')' << ' '; // 每次执行1次
            cout << endl; // 每次执行1次
            
        }
        cout << endl; // 每次执行1次
    }
    return 0;
}

就是 特别简单。

2.1.7 指数阶

即时间复杂度为 的算法。例如:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int fib(int n) {
    if(n == 0 || n == 1)
        return 1; // 执行1次
    else
        return fib(n - 1) + fib(n - 2); // 执行 2^n 次
}
int main() {
    int n; // 执行1次
    cin >> n; // 执行1次
    cout << fib(n) << endl;
    return 0;
}

我们可以看到,斐波那契数列的递归求解时间复杂度就是 O(2^n)

2.1.8 阶乘阶

即时间复杂度为 的算法。本时间复杂度太大太罕见,暂无代码示例(若实在想看,慢走不送)

2.2 计算时间复杂度

要计算的代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int arr[105];
int search(int target) {
    int left = 1, right = n;
    while(left <= right)
    {
        int mid = left + (right - left) / 2;
        if(arr[mid] == target)
            return mid;
        else if(arr[mid] > target)
            right = mid - 1;
        else
            left = mid + 1;
    }
    return -1;
}
int main() {
    int n, target;
    cin >> n >> target;
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    sort(arr + 1, arr + n + 1);
    cout << search(target) << endl;
    return 0;
}

首先把算法的执行次数写成一个多项式,就是把代码每一个部分写成一个单项式,然后相加得到多项式。

例如上面的代码就是 T(n) = 3 + n + LogN。

然后只保留最高阶项,若没有,就找出带有未知量的,就是LogN。

然后在去掉前面的系数,若没有,就不变。

然后把剩下的部分放到大O表示法的括号里面,完成!时间复杂度为:

3.总结

这就是我们今天学习的内容,内容比较多,希望大家好好消化。

再见!

相关推荐
列星随旋38 分钟前
线段树和树状数组的学习
学习·算法
楼田莉子1 小时前
C++17新特性:__had_include/属性/求值顺序规则
开发语言·c++·后端
全糖可乐气泡水2 小时前
Codex适配国产信创环境安装部署与技术适配全解析
开发语言·git·python·算法·百度
h_a_o777oah3 小时前
状态机+划分型 DP :深度解析K-划分问题下 DP 状态的转移逻辑(洛谷P2679 P2331 附C++代码)
c++·算法·动态规划·acm·状态机dp·划分型dp·滚动数组优化
05候补工程师3 小时前
从算法理想向工程现实的跨越:SLAM 核心架构、思维误区与 Nav2 实战避坑指南
人工智能·算法·安全·架构·机器人
手写码匠4 小时前
Android 17 适配实战指南:新特性解读、隐私变更与迁移全攻略
人工智能·深度学习·算法·aigc
雪度娃娃4 小时前
Asio异步读写——连接的安全回收问题
开发语言·c++·安全·php
珊瑚里的鱼4 小时前
leetcode42雨水
算法·leetcode
不吃土豆的马铃薯4 小时前
Spdlog 进阶:日志基本控制、日志格式控制、异步记录器
linux·服务器·开发语言·前端·c++
水木流年追梦5 小时前
大模型入门-大模型的推理策略
开发语言·python·算法·正则表达式·prompt