如何计算时间复杂度与空间复杂度

我们在做题目的时候,可能会看到各种各样的解题方法,那我们如何去衡量这些解题方法的好和坏?今天要学的时间复杂度和空间复杂度,就是用来衡量你算法好坏的标准

1. 时间复杂度

在计算机科学中,时间复杂度是一个函数 T(n), 这个 T(n) 函数式定量描述了程序中语句的执行次数, 映射到我们生活中,它的意思就是我完成一件事情所花费的时间

cpp 复制代码
void fun(int N)
{
    int count = 0;
    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < N; j++)
        {
        ++count; // 执行次数是 n*n,也就是 n^2
        }
    }
     for(int k = 0; k < 2 * N; k++)
    {
    ++count; // 执?次数是 2*n
    } 
    int M = 10;
    while(M--)
    {
        ++count; // 执?次数 10
    }
 }
 

在这个函数中fun 函数 ++count 语句的总执行次数:T (N) = N^2 + 2 × N + 10

由于 N ^ 2 是对执行次数影响最大的,所以我们在描述时间复杂度时会认为 O(n ^ 2)

如果你是第一次接触这个概念,你可能会说那我创建 count 变量、创建M变量这不需要时间吗?为什么我不去计算这两个操作所花费的时间呢?

其实是是因为我们的计算机是一个很强大的工具,它每秒呢能执行10^7到10^8次循环,而创建键 count 变量和 M 变量对计算机来说所需要消耗的时间太少了,所以我们并不去考虑它所消耗的时间

1.2 计算规则

1. 在 T(N) 只保留低阶项, 去掉低阶项

2.如果最高项存在且不是 1 ,则去掉常数系数

3. T(N) 中如果只有常数项,则认为时间复杂度为 O(1)

如果我们遇到递归 ,它时间复杂度的计算方法是每一次运行的时间复杂度×运行的次数

1.3 案例分析

cpp 复制代码
//从a[] 中找到 goal ,n 代表 a 数组的元素个数 
//如果找到就返回下标,否则返回 -1 
int find(int a[], int goal, int n) //
{
	for(int i = 0; i < n; i++)
	{
		if(a[i] == goal)
		{
			return i;
		}
	}
	return -1;
	
}

在这个 find 函数中最好的情况 for 循环需要执行一次,最坏的情况需要执行 n 次,平均需要执行 n / 2 次,由于计算规则需要去掉次数最高项的系数,所以时间复杂度为O(n)

2. 空间复杂度

空间复杂度的意思是一段程序需要运行起来,需要向电脑申请多大空间的内存

那我们可以想到,对于我们一个程序来说,最占空间的是什么?其实是数组吧,因为我们正常的去创建变量它所造成的空间开销并不会很大

cpp 复制代码
#define N 10
int main()
{
	int arr[N] = {42, 15, 93, 6, 28, 71, 55, 39, 84, 5 };
	int n = N;
	
	for(int i = 0; i < n - 1; i++)
	{
		for(int j = 0; j < n - 1 - i; j++)
		{
			if(arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp; 
			}
		}
	}
	
	for(int i = 0; i < n; i++)
	{
		cout << arr[i] << endl;
	}
	return 0;
}

大家可以看,这段代代码的目的是实现冒泡排序,无论你看不看得懂都没有关系,你只需要知道这个代码的功能是在 for 循环这个位置实现的

从哪里去计算我们这段代码的空间复杂度呢?就是在创建数组这个位置,就是int arr[n]

3. 常见复杂度增长关系

各种常见的时间复杂度的大小对比:

O(1) < O(logN) < O(N) < O(NlNlogN) < O(N ^ 2 ) < O(N ^ 3 ) < O(2 ^ n ) <N O(n!)

在大多数的算法竞赛中,C++它都有着1~2秒的时间限制,这意味着我们的程序执行次数要控在10^7~10^8之间

空间限制在128MB~256MB之间,可以创建3×10^7大小的int类型的数组,或者是5000×5000的二维数组,一般情况下都是够用的

这个表表格是用来计算空间复杂度的表格,首先你需要识别出来你的算法的空间复杂度是属于其中的哪个类型,再去看你的N是多大,以此判断你会不会超时

相关推荐
Tisfy11 小时前
LeetCode 1415.长度为 n 的开心字符串中字典序第 k 小的字符串:DFS构造 / 数学O(n)
数学·算法·leetcode·深度优先·字符串·dfs·模拟
永远睡不够的入11 小时前
C++list详解
c++·windows·list
FriendshipT11 小时前
算法部署知识点:TensorRT、Tensorflow、Flask、Docker、TFLite
算法·docker·flask·tensorflow
进击的小头11 小时前
第7篇:基于传递函数的PI控制器设计
python·算法
TracyCoder12311 小时前
LeetCode Hot100(62/100)——62. 不同路径
算法·leetcode·职场和发展
jing-ya11 小时前
day 50 图论part2
java·算法·深度优先·图论
仰泳的熊猫11 小时前
题目2268:蓝桥杯2016年第七届真题-密码脱落
数据结构·c++·算法·蓝桥杯
我能坚持多久11 小时前
【初阶数据结构09】——对堆用法的深入刨析
数据结构·算法
Yvonne爱编码11 小时前
二叉树高频题精讲 | 从入门到熟练掌握二叉树操作
java·开发语言·数据结构·链表·二叉树
kaikaile199511 小时前
基于PCNN和NSCT的图像融合MATLAB实现
开发语言·图像处理·算法·matlab