计算时间复杂度

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

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

再见!

相关推荐
巴里巴气4 小时前
第15题 三数之和
数据结构·算法·leetcode
小许学java4 小时前
数据结构-Map和Set
数据结构·算法·set·map·哈希表·哈希冲突·哈希桶
西阳未落5 小时前
LeetCode——双指针(进阶)
c++·算法·leetcode
一二学长5 小时前
异或相关的算法题
算法
暴力求解6 小时前
c++类和对象(下)
开发语言·c++·算法
艾莉丝努力练剑6 小时前
【Linux指令 (二)】不止于入门:探索Linux系统核心与指令的深层逻辑,理解Linux系统理论核心概念与基础指令
linux·服务器·数据结构·c++·centos
深栈6 小时前
机器学习:支持向量机
算法·机器学习·支持向量机
Mr_WangAndy6 小时前
C++设计模式_结构型模式_外观模式Facade
c++·设计模式·外观模式
FreeBuf_6 小时前
Happy DOM曝CVSS 9.4严重RCE漏洞,PoC已公开(CVE-2025-61927)
java·c语言·c++·python·php