01-时间复杂度与斐波那契数

1.时间复杂度

1.1 什么是时间复杂度

时间复杂度是指执行算法所需要的计算工作量。也就是说,执行一段代码时,每行代码要执行次数的总和。

1.2 大O表示法

大O表示法其实就是对时间复杂度的一个粗略估算,可以让开发者快速了解一段代码的执行效率。毕竟如果把每一段代码的时间复杂度都计算出来有点麻烦,另外对于常数来说影响不大。因此,在引入大O表示法时,就是把常数忽略。

1.3 时间复杂度计算的案例

  • 案例1
	for(int i = 0; i < n; i++ ) {
        for (int j = 0; j < n; j++) {
            NSLog(@"test");
        }
    }

如何计算上面那段代码的时间复杂度呢?
1.int i = 0 , 执行了1次
2.i < n, 执行了n次
3.i++, 执行了n次
4. for (int j = 0; j < n; j++) { NSLog(@“test”); } , 要执行n次
4.1 int j = 0, 执行了1次
4.2 j < n, 执行了n次
4.3 j++ , 执行了n次
4.4. NSLog(@“test”); , 执行了n次
最后算出来的次数是 1 + n + n + n * (1 + n + n + n) = 1 + 3n + 3n^2;
用大O表示表达法就是O(n^2)

  • 案例2
	for(int i = 0; i < n; i += i ) {
        for (int j = 0; j < n; j++) {
            NSLog(@"test");
        }
    }

如何计算上面那段代码的时间复杂度呢?
1.int i = 0 , 执行了1次
2.i+= i, 执行了log2(n)次
3.i < n, 执行了log2(n)次
4. for (int j = 0; j < n; j++) { NSLog(@“test”); } , 执行了log2(n)次
4.1 int j = 0, 执行了1次
4.2 j < n, 执行了n次
4.3 j++ , 执行了n次
4.4. NSLog(@“test”); , 执行了n次
最后算出来的次数是 1 + log2(n) + log2(n) + log2(n) * (1 + n + n + n) = 1 + 3log2(n) + 3nlog2(n);
用大O表示表达法就是O(nlogn)

1.4 常见的时间复杂度

执行次数函数举例非正式术语解释
12O(1)常数阶大部分程序的大部分指令之执行一次,或者最多几次。如果一个程序的所有指令都具有这样的性质,我们说这个程序的执行时间是常数。
2n+3O(n)线性阶如果程序的运行时间的线性的,很可能是这样的情况:对每个输入的元素都做了少量的处理。当N=1 000 000时,运行时间大概也就是这个数值;当N增长到原来的两倍时,运行时间大概也增长到原来的两倍。如果一个算法必须处理N个输入(或者产生N个输出), 那么这种情况是最优的。
3n2+2n+1O(n2)平方阶如果一个算法的运行时间是二次的(quadratic),那么它一般只能用于一些规模较小的问题。这样的运行时间通常存在于需要处理每一对输入 数据项的算法(在程序中很可能表现为一个嵌套循环)中,当N=1000时,运行时间是1 000 000;如果N增长到原来的两倍,则运行时间将增长到原来的四倍。
5log2n+20O(logn)对数阶如果一个程序的运行时间是对数级的,则随着N的增大程序会渐渐慢下来,如果一个程序将一个大的问题分解成一系列更小的问题,每一步都将问题的规 模缩减成几分之一 ,一般就会出现这样的运行时间函数。在我们所关心的范围内,可以认为运行时间小于一个大的常数。对数的基数会影响这个常数,但改变不会太 大:当N=1000时,如果基数是10,logN等于3;如果基数是2,logN约等于10.当N=1 00 000,logN只是前值的两倍。当N时原来的两倍,logN只增长了一个常数因子:仅当从N增长到N平方时,logN才会增长到原来的两倍。
2n+3nlog2n+19O(nlogn)nlogn阶如果某个算法将问题分解成更小的子问题,独立地解决各个子问题,最后将结果综合起来 (如归并排序,堆排序),运行时间一般就是NlogN。我们找不到一个更好的形容, 就暂且将这样的算法运行时间叫做NlogN。当N=1 000 000时,NlogN大约是20 000 000。当N增长到原来的两倍,运行时间超过原来的两倍,但超过不是太多。
6n^3 + 2n^2+3n+4O(n3)立方阶类似的,如果一个算法需要处理输入数据想的三元组(很可能表现为三重嵌套循环),其运行时间一般就是三次的,只能用于一些规模较小的问题。当N=100时,运行时间就是1 000 000;如果N增长到原来的两倍,运行时间将会增长到原来的八倍。
2^nO(2^n))指数阶如果一个算法的运行时间是指数级的(exponential),一般它很难在实践中使用,即使这样的算法通常是对问题的直接求解。当N=20时,运行时间是1 000 000;如果增长到原来的两倍时,运行时间将是原时间的平方!

各个时间负责度的对比如下图
在这里插入图片描述

所消耗的时间从小到大:
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

2.斐波那契数

题目:

一组数如下:
0,1,1,2,3,5,8,13…
求第n个数的值

结题思路:

通过观察,每个数,都是前两个数的和,则得出,f(n) = f(n-1) + f(n-2)

代码实现:

  • 实现方式一:递归算法
NSInteger jisuan1(int n) {
    NSInteger result = 0;
    if (n == 0) {
        result =  0;
    }
    if (n == 1) {
        result = 1;
    };
    
    if (n > 1) {
        result = jisuan1(n-1) + jisuan1(n - 2);
    }
    return result;
}

但是这种算法,效率特别低,但n等于64时,几乎就卡死了
该算法的时间复杂度如下:O(2^n)

  • 代码实现2
NSInteger jisuan(int n) {
    NSInteger first = 0;
    NSInteger second = 1;
    
    for (int i = 2; i < n; i++) {
        long tem = first + second;
        first = second;
        second = tem;
        NSLog(@"%ld", second);
    }
    return second;
}

这种方式会快速很多。时间复杂度如下:O(n)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值