数据结构和算法主要被用来解决“快”和“省”的问题。即要代码快速运行,又要节省空间,那么对时间和空间复杂度的分析便格外重要,尤其在数据量巨大的时候,这就是为什么BAT这种大公司面试时对算法和数据结构要求很高。
我们对大O表示法都很熟悉了,这里简略说下。它实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度,简称时间复杂度。
以下分享几个较实用的分析时间复杂度方法:
1. 只关注循环执行次数最多的代码
大O表示法我们只需要记住一个最大量级就行了,不需要关注小量级和他的系数,我们在分析一个算法、一段代码的时间复杂度的时候,也只关注循环执行次数最多的那一段代码就可以了。例如,CPU 的角度来看,每个代码的每一行都执行着类似的操作:读数据-运算-写数据。这里假设每行代码执行时间一样为unit_time,执行时间为(2n²+n+1)unit_time,大O表示法复杂度为O(n²),省略系数2和小量级n+1。
2. 加法准则
O(n²)+O(n)=O(n²)
总的时间复杂度就等于量级最大的那段代码的时间复杂度。
3. 乘法准则
O(n²)*O(n)=O(n³)
将乘法法则看成是嵌套循环。
时间复杂度量级可粗略分为两类:
多项式量级与非多项式量级。
其中非多项式量级只有两个:O(2ⁿ) 和 O(n!),这是非常低效的方法,不多讲。
多项式量级主要讲下O(logn),不管底数为2、3或10,将所有对数阶时间复杂度都记为O(logn),因为log₃n=log₃2*log₂n,对数都可以这样相互转化。
最好、最坏、平均、均摊时间复杂度分析
最好情况时间复杂度就是,在最理想的情况下,执行这段代码的时间复杂度。
最坏情况时间复杂度就是,在最糟糕的情况下,执行这段代码的时间复杂度。
平均时间复杂度,假设有n+1种情况,将n+1种情况的查找次数加起来除以n+1,即为平均查找次数。
若涉及到出现的概率问题,将每种情况出现的次数乘以各自出现的概率相加和即为平均时间复杂度,在概率论中此为期望值,即加权平均值,所得平均时间复杂度称为期望平均时间复杂度或加权平均时间复杂度。
均摊时间复杂度为平均时间复杂度的特殊情况,当每一次O(n)的插入操作时都伴随着n-1次的O(1)插入操作,将耗时多的操作均摊给接下来的耗时少的操作时时间复杂度就变为了O(1)。
空间复杂度
类比时间复杂度,空间复杂度全称就是渐进空间复杂度,表示算法的存储空间与数据规模之间的增长关系。
空间复杂度分析方法与时间复杂度类似,但它是指除了原本的数据存储空间外,算法运行还需要额外的存储空间。空间复杂度没有O(logn)这一类的,都是O(1),O(n),O(n²)。