时间复杂度和空间复杂度

复杂度

  1.     快(代码执行效率),省(代码占用更少的存储空间),是数据结构和算法要解决的问题。
  2.     时间复杂度是算法执行的时间,空间复杂度是算法占用的内存的内存大小。

 大 O 复杂度表示法

      1: 算法的执行效率,初略的讲就是代码的执行时间。分析的时候,假设每行代码执行一次命令的时间都是一样的(unit_time),用代码执行的总次数乘以unit_time,即为代码执行的时间。可以得出结论,所有代码的执行时间T(n)与每行代码的执行次数n成正比。总结公示如下:

                      T(n)=O(fn)

T(n) 代表代码执行的时间,n 表示数据规模的大小;f(n) 表示每行代码执行次数的相加总和。 O 表示代码执行时间T(n) 与 f(n) 表达式成正比。大O 表示法并不是代码实际的执行时间,而是代表代码执行时间随数据规模增长的变化趋势,所以也叫渐进时间复杂度,简称时间复杂度。

      2:f(n) 公示中的低阶,常量,系数三部分并不左右增长趋势,所以都可以忽略,只需要记录一个最大量级就可以。

      3: 时间复杂度分析比较实用的方法:

  •   只关注循环执行次数最多的一段代码
  •   总复杂度等于量级最大的那段代码的复杂度
  •    嵌套代码的复杂度等于嵌套内外代码复杂度的乘机

      4: 常见时间复杂度的量级

             常量阶 O(1),对数阶O(logn),线性阶级O(n),线性对数阶O(nlogn),平方阶O(n*n),立方阶级(n*n*n)...

            指数阶O(2的n次幂),阶乘阶O(n!)

      5: 空间复杂度

          表示算法存储空间与数据规模之间的增长关系。 例如 申请一个 大小为n 的数组

          int[] a =new int[n]; 空间复杂度就位 O(n)

最好,最坏,平均,均摊时间复杂度

      

// 在数组长度为m中查找某一个指定元素

int find(int[] arr,int n , int x){
   
   int position=-1;
   for(int i=0;i<n;i++){
      if(arr[i]==x){
         position=i;
         break; 
      }
       
   } 
   return position;
}

如果x 正好在数组的第一个元素,那么时间复杂度为O(1), 如果不在数组中,那么就需要遍历整个数组,时间复杂度为为O(n)。所以不同情况下这段代码的时间复杂度是不同的。因此,引入三个概念:

最好时间复杂度(在最理想的情况下,执行这段时间的时间复杂度)。

最坏时间复杂度(在最糟糕的情况下,执行这段时间的时间复杂度)。

平均时间复杂度

最好,最坏时间复杂度都是在极端的情况下,发生的概率并不是很大,所以引入平均时间复杂度。平均时间复杂度,需要引入概率论的相关知识。同样对上面代码进行分析:

假设数据x 在数组中和不在数组中的概率都为 1/2;要查找的数据出现在 0~n-1 的位置上的概率为 1/n; 一共有n+1种情况,在 0~n-1 位置上出现,和第n 中情况,不在数组中,所以 最后的公示为:

1*\frac{1}{2n}+2*\frac{1}{2n}+n*\frac{1}{2n}+n*\frac{1}{2n} =\frac{3n+1}{4}

这个值也叫加权平均值,也叫期望值。所以平均时间复杂度全称为加权平均时间复杂度,也叫期望时间复杂度。用大O表示发,去掉常量和系数阶,最后时间复杂度为O(n)。

实际上,我们并不需要考虑最好,最坏,平均时间复杂度,只有在同一段代码在不同情况下,时间复杂度出现量级的区别时候,才考虑使用这三种时间复杂度。

均摊时间复杂度(摊还分析法)

int[] array= new int[n];
int count=0;

void insert(int val){
   if(count==array.length){
     int sum=0;
     for(int i=0;i<array.length;i++){
      sum=sum+array[i]; 
     }
     array[0]=sum;
     count=1;
   }
   array[count]=val;
   ++count;
}

最好情况时间复杂度O(1)(数组没满,直接插入),最坏时间复杂度O(n)(需要遍历所有数组的值求和保存到 array[0]),平均时间复杂度也为O(1)。平均时间复杂度计算如下:

假设数组长度为n,根据位置的不同(有n中情况,数组中有空闲位置),我们插入位置的时间复杂度为O(1)。还有一种情况是数组没有位置,这个情况的时间复杂度为O(n)。 这n+1种情况的加权平均时间复杂度为:

1*\frac{1}{n+1}+1*\frac{1}{n+1}+....+n*\frac{1}{n+1}= \frac{n}{(n+1)}+\frac{n}{n+1}=\frac{2n}{n+1}

去掉常数阶和系数阶,平均时间复杂度为O(1).

insert 方法时间复杂度有一定规律,一般都是一个O(n) 之后,紧跟值n-1个O(1)。所以针对这个特殊的情况,我们引入摊还分析法,通过此法得到的时间复杂度,称为均摊时间复杂度,具体如下:

每一次O(n)的插入,都跟着n-1个O(1)的插入操作,所以把耗时多的那次操作均摊到接下来n-1次耗时少的操作上,均摊下来,这一组连续的操作均摊时间复杂度就是O(1)。均摊时间复杂特点,大部分时间复杂度都很低,只有个别情况时间复杂度比较高,而且这些操作存在前后连贯的性的时序关系

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值