代码调优 —— 时间复杂度

逻辑成本

今天在调优小伙伴代码的时候

偶然发现一个方法,逻辑上差不多是这样:

public static long demo (int i){

     if ( i <= 1) {
     return 1;
   }else{
     return i * demo( i - 1);
   }

}

其实正常来看没什么问题,编译执行都没问题,而且用了递归算法,基准情况值为1,

但其实这个递归用的并不好,实际上就是一个被包装的for循环,时间为O(N)

可修改成:

/**
 * @parm n为上面递归方法参数i
 */  
        long l = 0;
        for (int i = 0; i <= n; i++) {

            if (i <= 1) {
                l = 1;
            } else {
                l = i * l;
            }

        }

此递归被正常使用时,将其转成一个循环结构是相当困难的,分析将涉及求解一个递推关系,代码逻辑成本将提高。

 

时间成本

然后由此延展:

public static long demo (int i){

     if ( i <= 1) {
     return 1;
   }else{
     return demo( i - 1) + demo( i - 2);
   }

}

乍看此程序很高大上,可是可以测试一下,当i值为40左右时运行,这个程序的效率低的吓人。

简单分析一下,

令T(i)为调用函数demo(i)的运行时间。

如果i=0或者i=1,运行第一个ture逻辑返回常数1.

若i>2,则执行该方法的时间时第一行判断加上判断false后的运算——俩次方法调用和一次加法。

由于方法调用不是简单的运算,因此必须用方法内部外展分析,按照T的定义第一个调用它需要T(i-1)个时间单元。第二个调用要T(i-2)个时间单元,所以总时间需要T(i-1)+T(i-2)+2,2时值得第一行常数判断和false逻辑内加法运算,

所以: T(i)=T(i-1)+T(i-2)+2

因demo(i)=demo( i - 1) + demo( i - 2),由归纳法证明t(i)>=demo(i),归纳法定理,所以类似计算可以证明(当i>4时),从而看出程序时间以指数的速度增长。

所以如果更换成一个简单数组加上for循环,运行时间能显著降低。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值