斐波那契递归优化(指数函数计算优化)

题目描述

给你一个字符串,字符串只有0和1,现在要求,任意一个0的左边,必须挨着一个1才算合格,现在给你一个长度为N的字符串,请你返回所有合格的数量之和?
比如,N为2时,有00、11、01、10四种可能性,其中11和10符合,所以返回2。

思路分析

此题,输入是整数,输出是整数,其实,可以尝试用打表法,求出前几个结果,观察规律,就会发现,是斐波那契数列。
如果分析题目要求,尝试用递归解决:
首先,递归传入的参数是N,那么,递归的出口是什么?
因为前几个情况比较容易求出,当N=1时,返回1,当N=2时,返回2,因此,可以手算出前几个情况,作为base case。
一般情况的递归函数呢?
首先,此题有一个隐藏的递归条件,那就是,所有符合条件的可能性,开头必须是1,如果开头是0,则不符合,因此,此题如果给的是N,其实是在求N-1的递归结果,比如,题目给的N=8,那么,其实递归函数传参是7,这点需要注意。
考虑完这个特殊情况,那么,一般的递归函数,第一个位置,可以是0或者1,对吧?如果第一个位置是1,那么,情况和初始是一样的,前面有一个默认1,因为,第一个位置是1的后续递归就是F(N-1),如果第一个位置是0,那么,第二个位置,就必须是1,否则不符合了就,因此,第一个位置是0的情况,必须把第二个位置也定下来1,因此,后续的递归函数就是F(N-2)。
到此,F(N)=F(N-1)+F(N-2),推出了斐波那契数列。

斐波那契优化

类似于:F(N)=F(N-1)+F(N-2)
这种确定递推式的递归函数,是可以优化成O(logn)时间复杂度的。所谓的确定递推式,是指,有明确的递推关系,就可以,如果在递归函数中有判断和分支,那就不可以了。
优化技巧:
首先观察递推式,最大差值是N-2,那么差值就是2,就设置一个2X2的矩阵,这里需要用到线性代数的知识,不理解可以直接记住套路。
就拿斐波那契数列举例子,
f(3,2)=f(2,1) * {2x2的矩阵}
f(4,3)=f(3,2) * {2x2的矩阵}
利用这两个式子,就能求出这个2x2的矩阵。
求出矩阵后,上述式子,f(3,2)带入下面,就变成了f(4,3)=f(2,1) 乘以 {2x2的矩阵}的平方,对吧?因此:
然后F(N,N-1)=F(2,1)*{2x2矩阵}的n-2次方
因此,斐波那契数列问题就转化成了求解一个2x2矩阵的n-2次方的问题。

指数函数计算优化

一个质数函数的优化问题,比如10的75次方,怎么求?
笨方法就是,连乘75次,那时间复杂度就是O(N)级别的,如何优化成O(logn)级别呢?
利用二进制
比如,75用二进制表示就是1001011,那么就可以设置一个辅助值t,t的值就是底数10,然后结果值res的初始值为1。
然后,观察二进制表示的结尾是否为1,是1的话,res=res × t;
不是1,则二进制右移一位,变成100101。
然后t自己变成平方数,t=t × t
然后再次判断结尾是否为1,重复上述步骤。
最终res就是10的75次方。
总结
整个思路,相当于就是利用了将原始指数分解成二进制,利用二进制表示原本10进制的指数,然后,让一个底数变量和二进制指数同时成倍增长,并根据二进制上是0还是1来判断是否应该乘上此变量,最终实现每次累乘是2的次方数,从而实现O(logn)
代码:

    public static int f3(int di,int zhishu){
        int res=1;
        for (;zhishu!=0;zhishu>>=1){
            if((zhishu & 1)!=0){
                res=res*di;
            }
            di=di*di;
        }
        return res;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值