前言
现在的你
不知道现在的你是否碰到这样的困惑:
- 一直在写业务curd,看到别人一直从开发到架构师,自己只能羡慕;
- 看到大厂的jb数据结构和算法要求,心虚;
- LeetCode里面的最简单的题也答不对;
怎么办?
建议和我一起从0开始,补充一下自己再出发。
参考课程:https://www.bilibili.com/watchlater/#/BV1zJ411E7cg/p9
本系列文章主要是用php语言实现的基本算法,用来学习算法复杂度的分析。
具体生产环境建议优先选用PHP标准库
https://www.php.net/manual/zh/spl.datastructures.php
复杂度
-
渐进时间复杂度–算法写成的程序在执行时耗费时间的长度
一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数f(n),记作:
T(n) = O(f(n))
它表示随问题规模n的增大,算法执行时间的增长和f(n)的增长率相同 -
频度
语句的频度是指的是该语句重复执行的次数。
例:
//1、O(1) 常量阶
function func($n){
$x =0;
$x ++;
return $x;
}
//O(n) 线性阶
function func($n){
$x=0;
for($i=0;$i<$n;$i++){
$X++;
}
return $x;
}
//O(n^2) 平方阶
function func($n){
$x=0;
for($i=0;$i<$n;$n++){
for($j=0;$j<$n;$j++) {
$x ++;
}
}
return $x;
}
常见函数的增长:
我们希望着随着问题规模时间的增长复杂度是趋于稳定地上升,但上升幅度不能太大。
O(1) < O(logn)< O(n)< O(nlogn)< O(n^2)< O(2^n)< O(n!)
-
空间复杂度–算法写成的程序在执行时占用存储单元的长度
S(n) = O(f(n)), 其中n为问题的规模或大小。
空间复杂度(SpaceComplexity)是对一个算法在运行过程中临时占用存储空间大小的量度。
一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。
算法的输入输出数所占用的存储空间是由要解决的问题决定的,是通过参数表由调用函数传递而来的,它不随本算法的不同而改变。
如何确定算法时间复杂度
计算过程:
1、算出每一条语句的执行次数
2、求和,推导出一个n的表达式T(n)
3、找出同数量级的表示式(n的最高次方)
4、T(n)/同数量级–>常数
例1:
$n =10
for ($i =0;$i<$n;$i++){ //此处复杂度为n
for($j=0;$j<8;$j++) { //此处复杂度8*n
echo $i,$j; //此处复杂度为8*n
}
}
echo 100; //此处复杂度为1
计算过程:
1、参考代码注释
2、求和:T(n)=n+8n+8n+1=17n+1
3、确定同数量级n
4、(17n+1)/n = 17
时间复杂度: T(n) = O(n)
例2
$tmp = $i;
$j = $j;
$j = $temp;
以上每条频度都为1.该程序执行时间与问题规模n没有关系。即算法时间复杂度为常数级。
记作T(n) =O(1)
时间复杂度常用的记忆法:
1)访问数组中的元素是常数时间操作,或说O(1)操作。
2)一个算法如果能在每个步骤去掉一半数据元素,如二分检索,通常它就取O(logn)时间。
3)用strnatcmp比较两个具有n个字符的串需要O(n)时间。
4)常规的矩阵乘算法是O(n^3),因为算出每个元素都需要将n对 元素相乘并加到一起,所有元素的个数是n^2。
5)指数时间算法通常来源于需要求出所有可能结果。例如,n个元 素的集合共有2n个子集,所以要求出所有子集的算法将是O(2n)的。指数算法一般说来是太复杂了,除非n的值非常小,因为,在 这个问题中增加一个元素就导致运行时间加倍。