递归 | 分治
<目录
这两个算法有部分重合,所以一起讲。
递归 \(\sf\small\color{gray}Recursion\)
递归是递归函数的灵活运用。
说到底,它是一个 \(\color{blue}\texttt{C++}\) 的一个语言特性。
在函数内部调用函数,会使得思路更加清晰明了。
观察生活,很多事情随着规模或阶段的上升而变得越来越复杂。
然而,此规模或阶段往往又和前面的规模或阶段有着联系。
找出这个联系并解决问题的算法就叫递推。
这是我在 递推 | 差分与前缀和 里写过的一句话。
找出了关系,使用数组迭代,是递归。找出了关系,用递归函数迭代,就是递归。
递归的板子不是死的。它很活,视具体递推(归)式而变。
递归函数
int f(int a) { return f(a); }
这严格来说不算一个递归函数。它永远调用自己,造成 \(\sf\color{red}死递归\) 。
int f(int a) { return f(a-1); }
这样呢?
的确不是重复调用自己,可是 a
可以无限小下去,依然是死递归。
怎么办呢?
int f(int a) { if(a==1) return 1; return a+f(a-1); }
这样呢?
只要 a
是大于一的,那么这个函数就不会死。
递归函数三要素
\(\boxed{\sf调用自身}\boxed{\sf状态转移}\boxed{\sf递归边界}\)
此三者缺一不可,不然函数将失去意义。
运用递归函数
这里举一些例子,方便理解。
阶乘
使用递归函数求 \(\sf n!\) 的值。
此题用循环将非常简单。可是用递归函数呢?
调用自身是当然的。
我们按照递推的思想,把定义拆开:
边界呢?
自然是 \(1!=1\) 啦!
至此,思路已经非常清晰了。上代码!
int factorial(int a) { if(a==1) return 1; return a*factorial(a-1); }
斐波那契数
1 1 2 3 5 8 ...
我们在 递推 | 差分与前缀和 已经推过它的递推式了:
现在我们用递归实现。
int fibonacci(int a) { if(a==1) return 1; if(a==2) return 2; return fibonacci(a-1)*fibonacci(a-2); }
至此,有一个小问题暴露了:
F(n)
已经调用过 F(n-1)
和 F(n-2)
了,F(n-1)
又调用了 F(n-2)
,不就浪费资源了吗?
既然已经调用过,那我把它记住不就好了?
斐波那契数 - 记忆化搜索
每一次调用都看看有没有算过,如果算过,就直接拿出来用,没有就记住他。
int Ans[1000]; int fibonacci(int a) { if(Ans[a]!=0) return Ans[a]; if(a==1) return 1; if(a==2) return 2; Ans[a]=fibonacci(a-1)*fibonacci(a-2); return Ans[a]; }
算法优劣
递归肯定是没有递推优的。每一次调用函数都会新开空间,进入与返回也会花时间,递归层数一多,栈空间还可能炸。
那为什么还用递归?
如果你不知道递推层数,你怎么知道你要什么时候停下来?
而递归 if
里的东西什么都可以。
况且递归思维难度小啊。
分治 \(\sf\small\color{gray}Partition\)
分治分治,分而治之。
字面意思,把一个问题分成两个,三个甚至多个问题。
其实分治可以想递推一样,用循环解决,二分就是一种这样的例子。
还有的,就用递归函数解决吧。
运用
快速模
int FastMod(int a,int b,int k) { if(b==1)return a%k; const int o=FastMod(a,b/2,k)%k; if(b%2) return (a%k*o%k*o%k)%k; else return (o%k*o%k)%k; }
此处使用了 %
的性质,不熟悉的同学可以去学学 %
的性质。
区别
我认为吧,分治和递归的本质区别是,一个是由小一点的规模迭代而来,一个是由一半的,三分之一甚至四分之一的相同子问题迭代而来。
完结散花qwq
PCwqyy
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!