复杂度
算法的复杂度指的是执行该算法的程序在运行时所需要的时间和空间资源。时间复杂度不是代码真正的时间,而是数据规模的增长所表达的趋势。
算法的复杂度分析分为时间复杂度和空间复杂度。一般我们说的多的是算法的时间复杂度,希望通过较少时间执行算法程序。时间复杂度越低,算法的效率越高。
时间复杂度
时间复杂度就是运行的算法程序所需要的时间资源,取决于代码中量级最大的部分。下面将从a,b,c三个函数中分析时间复杂度。
function a() {
console.log(`恭喜发财a`);
return 666;
}
函数a打印字符串执行次数为1次
返回666,执行一次
执行总次数为2.时间复杂度为O(1)(所有常数的时间复杂度都是O(1))
function b() {
for (let i = 0; i < n; i++) {
console.log(`平安喜乐2`);
}
return 666;
}
for循环表达式执行n+1次
为什么不是n次?for循环表达式运行了n次,第n+1次比较之后不符合条件结束循环,所以执行n+1次。
打印字符串在for循环内部所以执行了n次(第n+1次比较不符合条件就结束循环不打印了)
return666执行一次
执行总次数为2n+2,时间复杂度为O(n)
拓展
在for循环的条件表达式中使用var定义的变量不是该循环的局部变量,而是与for循环处于同样的作用域中,即方法中使用var定义的变量i之后的代码都可以使用i。
let声明的变量是语句的局部变量。因为let作用域为块作用域,而此函数的块就是for循环中,所以let定义的i变量只能在for循环内部使用。
关于for循环表达式变量定义使用var和let的区别,如图所示
function c() {
let sum = 0; //1
let i = 1; //1
let j = 1; //1
for (; i < n; ++i) { //n
j = 1; //1*n
for (; j < n; ++j) { //n*n
sum = sum + i + j; //1*n*n
}
}
}
在函数c中,每行代码执行次数已经在上面代码中标出来了,循环内部的语句执行次数就是自身执行次数*循环执行次数,注意是否存在循环嵌套。
c函数中for循环表达式执行n次,因为是从1开始的哈哈哈,b函数是从0开始的。
在这个c函数中for循环的表达式省略写了, for (; i < n; ++i)是非常简洁的写法,省略了for循环的初始条件部分,代码的可读性略微降低,初始化部分移动到循环外,简洁但不推荐哈哈哈。
代码的所有组合情况无外乎循环,嵌套,递归。
常见的时间复杂度分析有O(1),O(logN),O(N),O(NlogN),O(N2),O(N3)
二分法是最典型的时间复杂度是O(logN)
看一下下面的代码
function d(n) {
let i = 1;
while (i <= n) {
i = i * 2;
}
return i;
}
代码的执行过程大概i2222>n,即i*2^n,反过来就是log₂n,n表示规模(指数函数与对数函数互为逆运算)
综上所述,本代码的时间复杂度为O(logN)
function d(n) {
let i = 1;
while (i <= n) {
i = i * 2;
}
return i;
//上面部分的时间复杂度是O(logN)
function cal(n) {
let sum = 0;//1
for (let i = 0; i < n; i++) { //n+1
sum += a(n)//n*O(logN) 那个1可以直接忽略
}
return sum;//1
}
}
通过以上的案例分析可以学到基于循环,嵌套,递归情况下的时间复杂度的分析,取决于代码中的最大量级的部分。关于时间复杂度的分析还可以分为最好情况下的时间复杂度,最坏情况下的时间复杂度,平均情况的时间复杂度,均摊时间复杂度。最好或者最坏可能取悦于原始数据的排序的不同顺序。
空间复杂度
空间复杂度是指运行算法的程序所使用的内存空间资源,在一些算法中可能会为了提升时间复杂度而提高空间复杂度,利用空间换时间。
下面通过一个简单的例子分析空间复杂度.
function e(n) {
const arr = [];
arr.length = n;
for (let i = 0; i < n; i++) {
arr[i] = i * i;
}
}
上述代码主要是定义一个数组,给数组定义长度,然后使用for循环为数组填充数据。,使用的内存空间就是数组的长度,即空间复杂度为O(n)。
常用的空间复杂度分析和常见的时间复杂度分析是相同的O(1),O(logN),O(N),O(NlogN),O(N2),O(N3)
间就是数组的长度,即空间复杂度为O(n)。
常用的空间复杂度分析和常见的时间复杂度分析是相同的O(1),O(logN),O(N),O(NlogN),O(N2),O(N3)