计算时间复杂度

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.总结

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

再见!

相关推荐
淡海水7 小时前
07-04-并发-ConcurrentBag-T-工作窃取WorkStealing算法
开发语言·算法·c#·bag·concurrent·workstealing
leobertlan7 小时前
好玩系列:训练一个神经网络模型指导小孩玩游戏2-大局观教练
算法
Tisfy8 小时前
LeetCode 3876.构造奇偶一致的数组 II:三种情况分类讨论(其实还是脑筋急转弯)
算法·leetcode·题解·脑筋急转弯
乐迪信息9 小时前
智慧港口船舶AI算法实现在线状态监测
大数据·人工智能·深度学习·算法·计算机视觉
木井巳11 小时前
【BFS/DFS 解决 FloodFill 算法】太平洋大西洋水流问题
java·算法·leetcode·深度优先·广度优先·宽度优先·推荐算法
心抵鹊11 小时前
归并排序之翻转对(hard)
数据结构·算法
白山编程大哥11 小时前
Java 集合算法:从排序、查找到底层原理的实战指南
java·python·算法
_Twink1e11 小时前
openJiuwen 实训营 Day 1 · WorkSwarm 入门教程
开发语言·c++·openjiuwen
shehuiyuelaiyuehao11 小时前
算法34,位运算符操作,总结
算法
Navigator_Z11 小时前
LeetCode //C - 1224. Maximum Equal Frequency
c语言·算法·leetcode