-
关于算法复杂度:
算法复杂度是我们来衡量一个算法效率的标准,主要分为时间复杂度和空间复杂度。时间复杂度就是指算法代码在运行最终得到我们想要的结果时所消耗的时间,而空间复杂度则是指算法中用来存储的数据结构所占用的空间。 -
大O复杂度表示法:
大O复杂度表示法描述算法的性能和复杂程度。举例如下:-
若执行每一行的时间都为 t,for 循环相当于执行了 n 次,所以这一段代码总执行时间为 (t+nt+nt+t) = (2n+2)t。function total(n) { var sum = 0; //t for (var i = 0; i < n; i++) { // nt sum += i; //nt } return sum; // t }
-
在第一个 for 循环执行 n 次的同时,第二个 for 循环执行了 n*n 次,这段代码总执行时间为(t+nt+n*n*t*2+t)=(2n*n+n+2)t。function total(n) { var sum = 0; // t for (var i = 0; i < n; i++) { //nt for (var j = 0; j < n; j++) { //n*n*t sum = sum + i + j; //n*n*t } } return sum; //t
上边两个函数的执行时间可以标记为 T(n) = O(2n+2) 和 T(n) = O(2n*n+n+2)。这就是大 O 时间复杂度表示法,它不代表代码真正的执行时间,而是表示代码随数据规模增长的变化趋势,简称时间复杂度。
当 n 很大时,我们可以忽略常数项,只保留一个最大量级即可。所以上边的代码执行时间可以简单标记为 T(n) = O(n) 和 T(n) = O(n2)。
-
-
时间复杂度分析
-
时间复杂度的取值
for (var i = 0; i < n; i++){ sum += i; }
在分析的时候,只需要关心哪个代码块循环次数最多的那段代码,比如说刚才的第一个例子,循环最多的代码块是这两行,循环都是n次。
-
最大值原则:总复杂度等于最大的代码块的复杂度
function total(n) { // 第一个 for 循环 var sum1 = 0; for (var i = 0; i < n; i++) { for (var j = 0; j < n; j++) { sum1 = sum1 + i + j; } } // 第二个 for 循环 var sum2 = 0; for(var i=0;i<1000;i++) { sum2 = sum2 + i; } // 第三个 for 循环 var sum3 = 0; for (var i = 0; i < n; i++) { sum3 = sum3 + i; } return {sum1:sum1, sum2: sum2, sum3:sum3} }
分别分析每一段循环时间复杂度,取他们最大的量级决定整段代码复杂度。
第一段,时间复杂度 O(n^2)。
第二段,时间复杂度可以忽略,循环执行了 1000 次,是个常数量级,尽管对代码的执行时间会有影响,但是当 n 无限大的时候,就可以忽略。
第三段,时间复杂度O(n)。
综上所述,所以上述代码的时间复杂度为 O(n^2)。
-
乘法原则:嵌套代码复杂度等于嵌套内外代码复杂度乘积
function f(i) { var sum = 0; for (var j = 0; j < i; j++) { sum += i; } return sum; } function total(n) { var res = 0; for (var i = 0; i < n; i++) { res = res + f(i); // 调用 f 函数 } }
total方法时间复杂度O(n),f方法的时间复杂度O(n)。所以整段代码的时间复杂度O(n2)。
-
常见的时间复杂度分析
对应的增长率如下图所示
时间复杂度可以分为两类,多项式量级和非多项式量级。其中,非多项式量级只有两个:O(2n) 和 O(n!),当数据规模 n 增长时,非多项式量级的执行时间就会急剧增加,所以,非多项式量级的代码算法是非常低效的算法。
-
-
空间复杂度分析
空间复杂度的话和时间复杂度类似推算。 所谓空间复杂度就是表示算法的存储空间和数据规模之间的关系。
时间复杂度的推算,忽略掉常数量级,每次数组赋值都会申请一个空间存储变量。function initArr(n) { var arr = []; for (var i = 0; i < n; i++) { arr[i] = i; } }
此函数的空间复杂度为 O(n)。
算法复杂度
最新推荐文章于 2024-02-25 18:14:50 发布