【算法训练营】一文“秒杀”时间复杂度


在这里插入图片描述

算法的时间复杂度

作用:通过分析算法时间复杂度来判断哪个程序更优秀
这里给大家列出数学上的解释:

时间频度(T(n)):语句执行的次数。
假定辅助函数f(n),当n趋近于无穷大时,T(n)/f(n)的极限为不为零的常数时,则记作T(n)=O(f(n))。
O(f(n))则是时间复杂度。

其实这里看不懂也没有关系,并不影响我们去计算时间复杂度。

忽略(极限思想):在计算时间复杂度时,经常会忽略一些对于算法整体的时间复杂度影响不大的项。例如:常数项、低次项、系数。

所以在计算时间复杂度时,一般要进行三步:

  1. 加法常数可忽略。
  2. 只保留最高阶项。
  3. 去除最高阶项的系数。

常见的时间复杂度

首先明确:递归的时间复杂度计算,其实就是:递归的次数*每次递归中的操作次数。 递归和树型结构是息息相关的。如果将递归的时间复杂度以树状来表示,就是二叉树节点个数*递归中操作次数。

  • 算法时间复杂度从小到大依次为(附带举例):
  1. 常数阶O(1)
int n = 1000;
System.out.println("Hello,World");
  1. 对数阶O(logn):对数阶可以忽略底数,证明方法略。
int i=1;
while(i<n){
    i=i*2;  //每次i*2距离n更近,程序只需要执行log以2为底n的对数次即可。即为logn。
}
  1. 线性阶O(n)
for(int i = 1; i<=n;i++){
	System.out.println("Hello,World");
}
  1. 线性对数阶O(nlogn):可以用上面提到的递归解法,递归次数*每次递归中的操作次数。
 pyblic static void calc(int l,int r){
	if(l>=r) return ;
	for(int i = l;i <= r ; i++){ /**print XXX **/   }
	int mid = (l+r) / 2;
	calc(l,mid);
	calc(mid+1,r);  //这里是分治算法,是对数阶。
}
calc(1,n);

因为使用了分治算法,这里每次递归中的操作次数都减半了,所以直接套公式不方便得出结论。
针对这种类型的题目可以这样理解:
在这里插入图片描述

  1. 平方、立方O(n^2),O(n^3):双重for循环、多重for循环。
  2. 指数阶O(2^n)
int fib(int n) {
	if(n < 2) return n;
	return fib(n - 1) + fib(n - 2);
}

解析如下:
在这里插入图片描述

  1. 阶乘O(n!)
    这里举一个利用回溯算法的例子,利用回溯算法可以解决排列/组合/子集之类的问题。这里先挖一个坑,暂不介绍。
//这是一个产生排列数的程序,时间复杂度当然是n!。
public void dfs(int depth){
        Boolean [] used = new Boolean[10];  //举例
        ArrayList per = new ArrayList() ; //举例
        if(depth == n){
            //print per
            return;
        }
        for(int i = 0;i<n;i++){
            if(used[i]) continue;
            used[i] = true;
            per.add(i);
            dfs(depth+1);
            per.remove(per.size()-1);
            used[i] = false;
        }
    }
    dfs(0);
  • 各种时间复杂度图解:
    在这里插入图片描述

平均时间复杂度、最坏时间复杂度、空间复杂度

  • 平均时间复杂度
    平均时间复杂度是指所有可能的输入实例等概率出现的情况下,算法的运行时间。

  • 最坏时间复杂度
    在讨论时间复杂度时,均指最坏情况下的时间复杂度。 保证了算法的运行时间不会超过最坏时间复杂度。

比如:

for (int i = 1, j = 1, sum = 0; i <= n; i++) {
            while (j <= n && sum + a[j] <= T) sum += a[j++];
            sum -= a[i];
        }

因为j是一直增加的,所以对于整段代码。最坏O(n)。对于每个i,内层最坏O(n),均摊O(1)。

  • 空间复杂度
    作用:度量算法在运行过程中临时占用存储空间的大小。
    在算法分析时,主要讨论时间复杂度,一些缓存产品和算法(基数排序)本质就是用空间换时间
    主要的计算:
    静态数组的长度。
    递归的深度(栈上消耗的空间)栈内存较少。
    动态new的空间(堆上消耗的空间)

附建议读者参考的资料: 代码随想录

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sivan_Xin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值