《数据结构和算法之美》学习笔记 Day 3

课程:《复杂度分析(下):浅析最好、最坏、平均、均摊时间复杂度》 总结

有时候,代码的时间复杂度在不同情况下会出现量级的差异。为了更全面、更准确的描述代码的时间复杂度,需要引入下面的概念。

四个复杂度分析的概念

  1. 最好情况时间复杂度(best case time complexity)
    代码在最理想的情况下执行的时间复杂度。
  2. 最坏情况时间复杂度(worst case time complexity)
    代码在最糟糕的情况下执行的时间复杂度。
  3. 平均情况时间复杂度(average case time complexity)
    代码在所有情况下的复杂度的加权平均值,即加权平均时间复杂度期望时间复杂度
  4. 均摊时间复杂度(amortized time complexity)
    在一组连续的具有时序关系的操作中,如果将这一组操作看成是一个整体,那么就可以将其中较高复杂度代码的执行时间平摊到复杂度较低的代码上面。然后再进行复杂度分析后得出的就是均摊时间复杂度,这种分析方法叫做摊还分析一般在这种特殊的场合中,均摊时间复杂度就是最好情况时间复杂度

下面以课后题作为案例分析:

// 全局变量,大小为10的数组array,长度len,下标i。
int array[] = new int[10]; 
int len = 10;
int i = 0;

// 往数组中添加一个元素
void add(int element) {
   if (i >= len) { // 数组空间不够了
     // 重新申请一个2倍大小的数组空间
     int new_array[] = new int[len*2];
     // 把原来array数组中的数据依次copy到new_array
     for (int j = 0; j < len; ++j) {
       new_array[j] = array[j];
     }
     // new_array复制给array,array现在大小就是2倍len了
     array = new_array;
     len = 2 * len;
   }
   // 将element放到下标为i的位置,下标i加一
   array[i] = element;
   ++i;
}
  • 最好情况时间复杂度
    最好情况就是当前数组中有空间存放添加的数据,即直接执行添加数据操作,这样代码的执行次数总和为常量级,所以最好时间复杂度为O(1)

  • 最坏情况时间复杂度
    最坏的情况是数组已满,需要重新申请两倍新数组空间和循环拷贝当前数组的元素到新数组中。假设当前数组的长度为n,根据大O复杂度分析方法可得代码的时间复杂度为O(n)

  • 平均情况时间复杂度
    分析可知,添加的元素可能存放的位置有1、2、3、4...n-1n种情况,以及数组满了需要新申请空间的情况,即总共n+1种情况,前面不需要申请空间的n种情况的时间复杂度都为O(1),需要申请空间的情况下的时间复杂度(即最坏时间复杂度)为O(n),假设每种情况的概率都相同,即1/(n+1),那么平均时间复杂度就为:

    平均时间复杂度

  • 均摊时间复杂度
    分析代码可知,每进行nO(1)的操作后,会紧跟一次O(n)的操作,如果将这些操作看作一个整体,将这一次O(n)的操作花费的时间平均在nO(1)的操作上,也就相当于代码多进行了一次O(1)的操作,即O(1) + O(1) = O(2) = O(1)

  • 下面是我从时间复杂度表示的意义出发,做的分析
    我们知道大O时间复杂度表示的是代码执行时间随数据规模增长的变化趋势。从这个角度出发,看这段代码。当数组的规模很大时,有足够的空间来存放添加的数据,那么代码的执行次数就会是常量级的。所以均摊时间复杂度为O(1)平均时间复杂度也为O(1).


上一篇:《数据结构和算法之美》学习笔记 Day 2
下一篇:《数据结构和算法之美》学习笔记 Day 4

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容