学习JS数据结构与算法(一)

171 阅读1分钟

时间复杂度是什么?

  • 一个函数,用大O表示,比如O(1)、O(n)、O(logN)....

  • 定性描述改算法的运行时间

src=http___img-blog.csdn.net_20180609210732780_&refer=http___img-blog.csdn.webp

简单的来说n的二次方 > n > log2n > 1

o(1)

let i = 0;
i += 1

每次执行这两行代码只会被执行一次,没有任何循环,所以时间复杂度为O(1)。

o(n)

for(let i = 0; i < n; i += 1){
    console.log(i);
}

for循环里的代码执行了n次,随着n的增大它也会随之增大就像上图中绿色的线一样,我们称这样的代码为O(n)时间复杂度的代码。

O(1)+O(n)=O(n)

let i = 0;
i += 1;
for(let i = 0; i < n; i += 1){
    console.log(i);
}

上述代码先执行了复杂度为O(1)的代码后又执行了复杂度为O(n)的代码,计算时间复杂度如果两个时间复杂度先后排列,我们就把它们相加,而且要取增长趋势更快的复杂度。上述代码中n比1增长更快,所以1就可以忽略不计了。

O(n)*O(n)=O(n^2)

for(let i = 0; i < n; i += 1){
    for(let j = 0; j < n; j += 1){
    console.log(i, j);
   }
}

当一个循环里嵌套了另一个循环,那么就得把两个时间复杂度相乘也就是 O(n)*O(n) 得出O(n^2)。

相乘则是正常的乘法 n * n = n^2,想加则是忽略增长趋势较小的时间复杂度取较大的时间复杂度。

O(logN)

let i = 1;
while (i < n) {
    console.log(i);
    i *= 2;
}

log函数就是求2的多少次方为n,上述代码就是一个典型的时间复杂度为logN的例子。在whil循环体里不断将 i *=2 ,其实就是不断在在求 2一次方、2的二次方、2的三次... 直到大于等于n为止,循环体里执行的次数就是logN次。这种代码其实就是时间复杂度为 logN

空间复杂度是什么?

  • 一个函数,用大于O表示,比如O(1)、O(n)、O(n^2)...

  • 算法在运行过程中临时占用存储空间大小的量度

      说白了就是你写的代码占用内存的多不多
    

o(1)

let i = 0;
i += 1

代码中声明了单个变量,单个变量所占用的内存永远是1,永远是恒定的一个内存。

o(n)

const list = [];
for (let i = 0; i < n; i += 1){
     list.push(i)
}

循环中将给ist添加n个值,它们相当于占用了n个内存单元,所以这段代码的空间复杂度为o(n)

o(n^2)

const matrix = []
for(let i = 0; i < n; i += 1){
    matrix.push([])
    for(let j = 0; j < n; j += 1){
       matrix[i].push(j)
   }
}

o(n^2)就像是矩阵,说白了就像是前端的行列,和栅格布局一样,每行里又有很多列。矩阵的本质其实就是一个二维数组,它存储了n的二次方个变量。

示例问题

  1. 如果一段代码中有3个循环,它们的循环次数都是n,那么这段代码的时间复杂度是 O(3n) 还是 O(n)? O(n)

    如果循环时并列的话就是每个循环的复杂度相加,即:O(n)+O(n)+O(n) =3O(n)。 复杂度是与常系数无关的,因为常系数的影响很小,几乎可以忽略不 计,所以这道题的时间复杂度为O(n)。

  2. 假设每天睡觉前,你都会数2的次方,1、2、4、8……,每次你都数到 n 才睡着,那么你数了几个数?时间复杂度是多少?

     假设到n数了x个数,那么就构成下面的等式:2^x = n => x = log2n(以2为底)
     时间复杂度就是以2为底的logn