算法时间复杂度分析

算法时间复杂度分析

大O记法

定义:

​ 在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随着n的变化情况并确定T(n)的量级。算法的时间复杂度,就是算法时间的量度,记做:T(n) = O(f(n))。它表示随着问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度,其中f(n)是问题规模n的某个函数。

用大写O()来体现算法时间复杂度的记法,我们称之为大O记法。一般情况下,随着输入规模n的增大,T(n)增长最慢的算法为最优算法。

使用大O记法表示算法的时间复杂度的几个规则:

1、用常数1取代运行时间中的所有加法常数

public static void main(String[] args) {
        //计算1 ~ 100的和
        int n = 100;	//1次运算
        method1(n);
    }

    private static void method1(int n) {
        int sum = (1 + n) * n / 2;		//1次运算
        System.out.println(sum);
    }

一共执行2次运算,由规则1可知,时间复杂度为 O(1);

2在修改后的运行次数中只保留最高阶项

public static void main(String[] args) {
        //计算1 ~ 100的和
        int n = 100; 	//一次运算
        method2(n);
    }

    private static void method2(int n) {
        int sum = 0;	//一次运算
        for (int i = 1; i <= n; i++) {
            sum += i;
        }				//n次运算
        System.out.println(sum);
    }

一共进行n + 2次运算,先根据规则1,得到n + 1再根据规则2,得到时间复杂度为:O(n)

3、如果最高阶存在,且与之相乘的常数不为1,则去除与这个项相乘的常数;

public static void main(String[] args) {
        int n = 100;		//一次运算
        int sum = 0;		//一次运算
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                sum += j;
            } 	//n次运算
        }		//n次运算
        System.out.println(sum);
    }

一共运算n^2 + 2次,先根据规则1,再根据规则2,再根据规则3,得出时间复杂度为O(n^2);

常见的大O阶

1、线性阶

**一般含有非嵌套循环涉及线性阶,线性阶就是随着输入规模的扩大,对应计算次数成直线增长,**例如:

public static void main(String[] args) {
        int n = 100;
        int sum = 0;
        for (int i = 0; i < n; i++) {
        	sum += i;    
        }
        System.out.println(sum);
    }

上面这段代码,它的循环的时间复杂度为O(n),根据规则以及循环体中的代码的执行次数进行判断

2、平方阶

一般为嵌套循环

public static void main(String[] args) {
        int n = 100;
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                sum += j;
            }
        }
        System.out.println(sum);
    }

n = 100,也就是说,外层循环执行一次,内层循环执行100次,那么总程序一共需要执行100 * 100次,也就是n2次,所以这段代码的**时间复杂度为O(n2)**

3、立方阶

一般为三层嵌套循环

public static void main(String[] args) {
        int n = 100;
        int sum = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for(int k = 0; k < n; k++){
                    sum += k;
                }
            }
        }
        System.out.println(sum);
    }

同理,程序一共要执行 100 * 100 * 100次,所以时间复杂度为O(n^3)

4、对数阶
public static void main(String[] args) {
        int n = 100;
        int i = 1;
        while(i < 100){
            i *= 2;
        }
    }

由于每次i * 2之后,值逐渐变大,假设有x个2相乘后大于n,退出循环,得2^x = n, 既x = log(2)n,所以时间复杂度为O(logn)

对于对数阶,由于随着输入规模n的增大,不管底数为多少,他们的增长趋势是一样的,所以我们会忽略底数。

常见时间复杂度总结

描述增长的数量级说明举例
常数级别1普通语句两数求和
对数级别logN二分策略二分查找
线性级别N循环求和,遍历查找
线性对数级别NlogN分支思想归并排序
平方级别N^2双层循环二维数组遍历
立方级别N^3三层循环检查所有三元组
指数级别2^N穷举查找检查所有子集

时间复杂度排序

O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3)

在优化算法时,尽可能的追求的是O(1),O(logn),O(n),O(nlogn)这几种时间复杂度,而如果发现算法的时间复杂度为平方阶、立方阶或者更复杂的,那么我们就认为这种算法时不可取的,需要优化

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值