计算时间复杂度

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

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

再见!

相关推荐
Dream it possible!16 小时前
LeetCode 面试经典 150_二叉搜索树_二叉搜索树的最小绝对差(85_530_C++_简单)
c++·leetcode·面试
xxxxxxllllllshi16 小时前
【LeetCode Hot100----14-贪心算法(01-05),包含多种方法,详细思路与代码,让你一篇文章看懂所有!】
java·数据结构·算法·leetcode·贪心算法
前端小L16 小时前
图论专题(二十二):并查集的“逻辑审判”——判断「等式方程的可满足性」
算法·矩阵·深度优先·图论·宽度优先
铁手飞鹰16 小时前
二叉树(C语言,手撕)
c语言·数据结构·算法·二叉树·深度优先·广度优先
麦烤楽鸡翅17 小时前
简单迭代法求单根的近似值
java·c++·python·数据分析·c·数值分析
专业抄代码选手18 小时前
【Leetcode】1930. 长度为 3 的不同回文子序列
javascript·算法·面试
[J] 一坚18 小时前
深入浅出理解冒泡、插入排序和归并、快速排序递归调用过程
c语言·数据结构·算法·排序算法
czlczl2002092518 小时前
算法:二叉搜索树的最近公共祖先
算法
司铭鸿18 小时前
祖先关系的数学重构:从家谱到算法的思维跃迁
开发语言·数据结构·人工智能·算法·重构·c#·哈希算法
sulikey19 小时前
C++ 四十年:一段跨越时代的语言旅程
c++·c++40周年