复杂度分析(1)-渐进复杂度,空间复杂度

最近杨振宁和姚期智的回到中国国籍的事情非常热闹,作为一个在中国想做coding相关工作的人,你就不应该不知道清华姚班这个神奇的存在。老子这辈子是没有一丝机会达到那个高度了,但是我要努力使我儿子有机会够到那个高度,哈哈哈,开玩笑。但是,这和这个章节的题目有什么关系呢?那我因为我早上在知乎上看了一下Aady Yao的研究成果:

早在博士就读期间,姚期智提出了随机化算法复杂度的论证,而如今已经成为研究者无人不知的重要工具。
在 1977 年的论文中,姚期智提出了Yao's min-max principle,这一原理成为了推理随即算法与复杂度的基本技术,也已经应用于属性测试与学习理论等领域。

没错,那就是关于复杂度的分析,真的是太难了,要对复杂度有一个深刻的理解,我觉得首先要深刻理解计算机系统。即便如此,我也还是得写一点简单的总结, 万事都是要开头,你才会继续去做的!

常数O(1)
这里有一个简单的问题,我们要对三个数进行排序,并输出最大元素。不妨取前三个元素x=S[0], y=S[1], z=S[2], 这一步只需要执行三次(从特定单元提取元素),耗费O(3)时间。接下来,为确定这三个元素的的大小顺序,最多需要三次排序,也是O(3)时间,最后输出最大的元素需要O(1)时间。

T(n) =O(3)+O(3)+O(1)=O(7)=O(1)

运算时间可表示和度量为T(n)=O(1)的这一类算法,统称为”常数时间复杂度算法”,也称为就地算法。

对数O( logn )
考察如下问题:对于任意非负整数,统计其二进制展开中位数1的总数。

int countOnes(unsigned int n){
    int ones=0while(n>0){
        ones+=(1&n);
        n>>1;
    }
}

根据右移运算的性质,没右移一位,n至少缩减一半,也就是说,至多经过1+ log2n 次循环,n必然缩减至0,从而算法终止。实际上从另一个角度上讲,1+ log2n 恰好为n二进制展开的总位数,每次循环都将其右移一位,总的循环数也应是1+ log2n
所以countOnes的算法执行时间主要由循环的次数决定:
O(1+ log2n )=O( log2n )
在对数时间复杂度里面, log2n 实际上与底数无关,底数2可以换成其他任何数。

线性O(n)
关于线性时间复杂度,我们可以改进一下countOne算法:

int countOnes(unsigned int n){
    int ones=0while(n>0){
        count++
        n&=n-1;
    }
}

这个算法巧妙地通过位运算技巧,自低向高逐个地将位数1转置为0。
以上计算过程中,仅涉及整数的减法和位与运算各一次。若不考虑机器的位长限制,各只需要O(1)时间因此,这个新算法的运行时间,应线性正比于n的二进制展开中位数1的实际数目。

指数O( 2n )


--int64 power2BF_I(int n){
    __int64 pow=1;
    while(n-- >0){
         pow<<=1;
    return pow;
}

这里的power2BF_I算法是由n轮迭代组成的,各需做一次累乘和一次递减,均属于基本操作,故整个算法时间共需O(n)时间。但是若以输入指数n的二进制位数r=1+ log2n 作为输入规模,则运行时间为O( 2n )。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值