算法的时间复杂度和空间复杂度总结

  1. 如何衡量一个算法的好坏?
    时间复杂度+空间复杂度
  2. 什么是时间复杂度?
    时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,他定量的描述了该算法的运行时间。一个算法执行所耗费的时间,理论上来说是不能算出来的,只有你把程序放在机器上跑起来才能知道。但是这样是很麻烦的。所以才有了时间复杂度。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。
  3. 时间复杂度为什么不使用时间来衡量而使用基本语句的运行次数来衡量?
    因为程序的运行环境不同,同一个程序在不同配置的机器上的运行时间不同,在配置较好的机器上的运行时间肯定要优于配置较差的机器。因此使用时间来衡量会有误差。然而基本语句的执行次数是不受环境影响的。因此不使用时间来衡量而使用基本语句的运行次数来衡量。
  4. 时间复杂度的O渐进表示法
    实际上我们计算时间复杂度时,不用计算出精确地执行次数,只需要大概的执行次数,这里就使用大O的渐进表示法。
    大O符号:是用于描述函数渐进行为的数学符号。
    推导大 O阶方法:
    (1)用常数1取代运行时间中的所有加法常数。
    (2)在修改后的运行次数函数中,只保留最高阶项。
    (3)如果最高阶项存在且不是1,则去除与这个项相乘的常数。得到的结果就是大O阶。
  5. 时间复杂度的:最优、平均、最差情况,为什么时间复杂度看的是最差情况?
    一般来说,我们希望获得一个算法的时间效率下限,因为所有人都喜欢某种保证:即算法无论如何不会低于我们保证的效率。这种分析就是所谓的最坏情况分析。最坏情况分析指的是在给定输入尺寸的情况下,一个算法运行的效率的下限。
    最坏情况运行时间是一种保证,那就是运行时间将不会再坏了。在应用中,这是一种最重要的需求,通常,除非特别指定,我们提到的运行时间都是最坏情况的运行时间。
    (1)
    最差情况下的复杂度是所有可能的输入数据所消耗的最大资源,如果最差情况下的复杂度符合我们的要求,我们就可以保证所有的情况下都不会有问题。
    (2)
    某些算法经常遇到最差情况。比如一个查找算法,经常需要查找一个不存在的值。
    (3)
    也许你觉得平均情况下的复杂度更吸引你,可是平均情况也有几点问题。第一,难计算,多数算法的最差情况下的复杂度要比平均情况下的容易计算的多,第二,有很多算法的平均情况和最差情况的复杂度是一样的. 第三,什么才是真正的平均情况?如果你假设所有可能的输入数据出现的概率是一样的话,也是不合理的。其实多数情况是不一样的。而且输入数据的分布函数很可能是你没法知道。
    (4)
    考虑最好情况的复杂度更是没有意义。几乎所有的算法你都可以稍微修改一下,以获得很好的最好情况下的复杂度(要看输入数据的结构,可以是O(1))。怎样修改呢? 预先计算好某一输入的答案,在算法的开始部分判断输入,如果符合,给出答案。
  6. 如何求解:二分查找、递归求阶乘、递归斐波那契的时间复杂度?

二分查找:

#include<stdio.h>
#include<stdlib.h>
int Binary_Search(int* arr, int key, int right, int left) {
	int mid = 0;
	while (left < right) {
		int mid = (left+right)/2;
		if (arr[mid] < key) {
			left = mid + 1;
		}
		else if (arr[mid] > key) {
			right = mid - 1;
		}
		else {
			return mid;
		}
	}
return -1;
}
int main() {
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int left = 0;
	int right = 9;
	int key = 5;
	int result = Binary_Search(arr, key, right, left);
	printf("%d", result);
	return 0;
	system("pause");
}

最好执行一次,最坏执行O(logN)次。时间复杂度为:O(logN)
2^m=N
m=logN.
递归求阶乘:

long long Factorial(size_t N) {
	return N < 2 ? N : Factorial(N - 1)*N;
}

递归了N次,时间复杂度为O(N)。
递归斐波那契:

long long Fib(size_t N) {
	if (N < 3) {
		return 1;
	}
	else {
		return Fib(N - 1) + Fib(N - 2);
	}
}

递归操作了2^N 时间复杂度为O(2^N)。
7. 什么是空间复杂度?
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。
8. 如何求空间复杂度? 普通函数&递归函数
和时间复杂度类似,也是用大O渐进表示法。
9. 分析递归斐波那契数列的:时间、空间复杂度,并对其进行优化,伪递归优化—>循环优化

long long Fib(size_t N) {
	if (N < 3) {
		return 1;
	}
	else {
		return Fib(N - 1) + Fib(N - 2);
	}
}

时间复杂度:2^N 空间复杂度:O(N)
伪递归优化

long long Fib(int first,int second,size_t N) {
	if (N < 3) {
		return 1;
	}
	if (N == 3) {
		return first + second;
	}
	return Fib(second, first + second, N - 1);
}

时间复杂度:O(N) 空间复杂度:O(N)
循环优化

int fib(int n) {
	int last1 = 1;
	int last2 = 1;
	int cur = 0;
    if (n == 1 || n == 2) {
		return 1;
	}
	for (int i = 3; i <= n; i++) {
		cur = last1 + last2;
		last2 = last1;
		last1 = cur;
	}
	return cur;
}

时间复杂度:O(N) 空间复杂度:O(1)
10. 总结常见时间复杂度
常见时间复杂度:
在这里插入图片描述
注意,经常将log2n(以2为底的对数)简写成logn。
常见时间复杂度之间的关系:
在这里插入图片描述
所消耗的时间从小到大

O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值