有没有想过一个问题
如果我要遍历(或者说考虑这个问题的每个情况)是不是最少对每个情况都进行一次处理?
但这是O(n)级别的,那O(logn)哪里来的呢?(省流:比如二叉搜索树的搜索,二进制<-而这些其实都体现了二分法的思想,二分的思想主要用于遍历问题,可以把大的问题跳跃性的拆成小的问题)
很简单,因为我们跳过了重复的计算(实现上来讲是记住了可以重复利用的结果)<-注意这里我讲的是“记住了可以重复利用的结果”而不是“保存结果以重复利用”这点我举个例子:
举例必备------万能的斐波那契数列
O(2^n)解法:递归
因为递归程序将函数压入了程序栈,构成了逻辑树(思维导图)的层------听不懂的话就这么理解:每次递归有两个出口(形成分支),构成了一个二叉树
优化---O(n)解法:递推/记忆化递归
通过建一个记忆化数组的方式,将所有计算过的结果存起来,这样只需要调用即可。对于每一个数据,只做一步处理,就是把它前面的数(结果)与再前面的那个数(结果)相加
这样的话,不管是递推还是递归,都能避免重复计算哩(喜)
可是如果一道题给你,连O(n)解法都超了,那怎么办?
我知道你很急,但你先别急
我们来看下面这道题
“最少用多少个不同的正整数(不可重复使用),使其相互之间用求和的方式可以表示出从1到100以内所有的正整数”
样例:2=1+1
3=1+2
7=1+2+4
9=1+8
10=2+8
所以让它能表示从1到10内所有的整数,我们只需要1 ,2 ,4和8即可
看到这几个数字,想必大家都知道是啥意思了,就是2的0,1,2,3次方。原理上简单一点的话可以理解成二分查找或者是二进制,复杂一点的话,其实是个四层的二叉搜索树。但不管怎么样,我确实只用四个数就可以表示从1到10甚至是1到15内的所有的数。
你看,logn这不就来了吗?
我们回到刚刚的斐波那契数列
O(logn)写法:矩阵快速幂
呃,这个我考虑一下,到底要不要写。。。。因为这个东西实在太长了,一时半会儿讲不清楚,我在这里先扔个链接吧 哔哩哔哩上的https://b23.tv/x1rOxC5【竞赛向】斐波那契数列的矩阵快速幂求法-哔哩哔哩
讲的挺好的,可以看一下。我写这篇文章,只是为了帮助你们理解这个问题的(其实)。。。[坏笑]
因为我觉得他前半段讲的很好,就是说因为两两线性相关,所以想到用矩阵来处理。但是后半段讲的就有点拉垮,可以结合着我这篇文章来看看(就是他把指数[幂]等那个树,我像我的那个引例一样进行了多次二分。而那种二分的实现,其实只需要取出它的二进制数就可以了。这样的话就可以做到只存储A的一次方,二次方,四次方…这些结果,就可以快速的计算出任意给定的n。而唯一需要计算的两个部分就是存储的结果和最后算n的那一步,算n只要一步,这没问题,而算a的次方的二次方是由一次方平方得来的,四次方是由二次方平方得来的…同样我每算一个结果只需要进行一次运算)
写在后面:
我第一篇文章能有那么多阅读量,我真的很感动QAQ。我寻思着我就一小白,居然还有人看我这些奇思妙想[感谢][感谢]
就当茶余饭后的消遣吧😂
2024/02/18
现在学到区间维护与查询(ST,RMQ,LCA)了
看了看当年写的东西(好羞耻啊),其实上面我称为“二进制拆分”的操作叫倍增,“查询操作”指的是建ST表或线段树并查询。好感慨啊,第一次发是在两个月前,起初只是为了记录一下自己的“奇怪”想法,可学着学着才发现,原来这根本不是什么丢人的事。我思故我在。加油