# 1.复杂度:如何衡量程序运行的效率?

# 1-1 复杂度是什么?

  • 复杂度是衡量代码运行效率的重要的度量因素;
  • 首先,这段代码消耗的资源是什么?(消耗计算时间和计算空间)
  • 其次,这段代码对于资源的消耗是多少?
  • 复杂度是一个关于输入数据量 n 的函数;
  • 计算复杂度与具体的常系数无关;O(n) 与 O(2n) 表示一样的复杂度
  • 多项式级的复杂度相加的时候,选择高者作为结果; O(n2) + O(n)与 O(n2) 表示一样的复杂度
  • O(1) 也表示一个特殊的复杂度,与输入数量n无关

# 1-1-1 实例分析

下面看一个实例:输入数组a = [1,2,3,4,5],要求输出数组b,值为[5,4,3,2,1]

方法一:定义并初始化一个b数组,数组长度等于a数组,且每一个元素为0,通过for循环,从左到右将a数组从右向左赋值给b

  • 初级做法
 function s1_1(){
  let a = [1,2,3,4,5];
  let b = Array(5).fill(0);
  for(let i = 0; i < a.length;i++){
    b[a.length - i - 1] = a[i]
  }
  return b;
 }
  • 优化后

以上方法,时间复杂度与数组长度有关,为O(n);空间复杂度,即重新定义了b数组,与a数组同等长度,为O(n);
方法二:定义一个中间变量temp,然后取a的一半数据,交换位置,再将值return

 function s1_2(){
  let a = [1,2,3,4,5];
  let temp;
  for(let i = 0; i < a.length/2;i++){
    temp = a[i];
    a[i] = a[a.length - i - 1];
    a[a.length - i - 1] = temp;
  }
  return a;
 }

以上方法,时间复杂度为O(n/2),也就是O(n);
空间复杂度,需要一个temp变量,它与数组长度无关,不论数组多长,它都只需要一个temp变量,所以空间复杂度,为O(1);

# 1-1-2 总结:

总结:对于同一个问题,采用不同编码方法,对时间和空间的损耗是有可能不一样的

# 1-2 时间复杂度与代码结构的关系

时间复杂度,与代码结构有非常强的关系

# 1-2-1 实例分析1:

下面看一个实例:定义一个数组a = [1,4,3],查找数组a中的最大值

 function s1_3(){
   let a = [1,4,3]
   let b = -1;
   for(let i = 0; i < a.length; i++){
     if(a[i] > b){
       b = a[i]
     }
   }
   return b;
 }

以上方法,时间复杂度,就是将数组遍历一遍,也就是O(n);

# 1-2-2 实例分析2:

下面看再一个实例:定义一个数组a = [1,3,4,3,4,1,3],查找数组中出现次数最多的那个数组

 function s1_4(){
   let a = [1,3,4,3,4,1,3];
   let max_val = -1;
   let max_time = 0;
   let time_temp = 0;
   for(let i = 0;i < a.length;i++){
      time_temp = 0;
      for(let j = 0; j < a.length; j++){
        if(a[i] === a[j]){
          time_temp++
        };
      }
      if(time_temp > max_time){
        max_time = time_temp;
        max_val = a[i];
      }
   }
   return max_val
 }

这段代码中,使用了双循环,时间方面的消耗就是n*n,即时间复杂度O(n);
由以上例子,我们可以做以下结论:

# 1-2-3 总结:

  • 一个顺序结构的代码,复杂度为O(1)
  • 二分查找,采用分而治之的二分策略,时间复杂度为O(logn)
  • 一个简单的for循环,时间复杂度为O(n)
  • 两个顺序执行的for循环,时间复杂度是O(n)+O(n)=O(2n),其实也是 O(n)
  • 两个嵌套的for循环,时间复杂度为O(n2)

# 1-3 降低时间复杂度的必要性

很有必要,不同的时间及空间复杂度,会直接影响到计算次数

# 1-4 总结

复杂度细分为时间复杂度和空间复杂度,其中时间复杂度与代码的结构设计高度相关;
空间复杂度与代码总数据结构的选择高度相关

  • 1.复杂度它与具体常系数无关;O(n) 与 O(2n)表示一样的复杂度
  • 2.复杂度相加时,选择高者作为结果;也就是说 O(n²)+O(n) 和 O(n²) 表示的是同样的复杂度
  • 3.O(1) 也是表示一个特殊复杂度;即任务与算例个数 n 无关