当前位置: 首页 > news >正文

【左程云算法020】递归和master公式

文章目录

  • 从思想上理解递归
  • 从实际上理解递归
  • 任何递归函数都一定可以改为非递归
  • 递归改为非递归的必要性
  • Master公式
    • 所有子问题规模相同的递归才能用master公式,T(n) = a*T(n/b)+0(n^c),a\b\c都是常数
    • 如果log(b,a) < c,复杂度为:O(n^c)
    • 如果log(b,a) > c,复杂度为:O(n^log(b,a))
    • 如果log(b,a) == c,复杂度为:O(n^c*logn)
    • 一个补充:T(n) = a*T(n/b)+0(n*logn),时间复杂度是O(n*((logn)的平方)),证明过程比较复杂,记住即可

视频链接
【算法讲解020【必备】递归和master公式】
在这里插入图片描述

从思想上理解递归

给定一个数组,我想用递归的写法在其中找最大值

public class Video_020_MaxValue{
return f(arr,0,arr.length-1);
}
//arr[l...r]范围上的最大值
public static int f(int[] arr,int l,int r){
if(l==r){//说明只有一个数了,那最大值就是它本身 也叫base case 就是简单到不能再划分
return arr[l];
}
int m = (l+r)/2;//如果不止一个数,切除中点
int lmax = f(arr,l,m);//左侧的最大值求出来
int rmax = f(arr,m+1,r);//右侧的最大值求出来
return Math.max(lmax,rmax);//整体的最大值就是左边的最大值和右边的最大值求最大
}
public static void main(String[] args){
int [] arr = {3,8,7,6,4,5,1,2};
System.out.println("数组最大值:"+maxValue(arr));}

在这里插入图片描述

比如求解第0-3位上的最大值

即为求f(0,3)
左边拆解为->f(0,1)
                              ->左边拆解为f(0,0)->最大值是4
                              ->右边拆解为f(1,1)->最大值是2

所以f(0,1)综合左最大值和右最大值,是4

右边拆解为f(2,3)
                              ->左边拆解为f(2,2)->最大值是6
                              ->右边拆解为f(3,3)->最大值是1

所以f(0,1)综合左最大值和右最大值,是6

所以综合最大是6
在这里插入图片描述

从实际上理解递归

系统再运行递归的时候是在系统栈进行的
f(0,3)没中data base
所以求mid=1

int m = (l+r)/2;

紧接着下一行

int lmax = f(arr,l,m);

我调用了一个新的子过程
系统会把你所有的参数位,临时变量压到栈里面,等着lmax,此时这个函数就销毁了(f(0,3)就销毁了,现在要的是f(0,1))
在这里插入图片描述
f(0,1)中点是0,现在又跑不下去了
又来到了

int lmax = f(arr,l,m);

所以和上面一样
又把参数位,临时变量压到栈里面并销毁原函数(即f(0,1))
在这里插入图片描述
现在就跑f(0,0)
正好指向database,所以说返回4,把这个返回值返回给当前的栈顶
这一行弹出来这个状态
在这里插入图片描述
这时候该跑
int rmax = f(arr,m+1,rmax);
又跑不动
继续压回栈,销毁…
在这里插入图片描述
求f(1,1),正好中了data base,将返回值2返回栈顶,状态这一行弹出
在这里插入图片描述
都具备了可以继续往下进行了

return Math.max(lmax,rmax);

返回4给栈顶,又跑不动了
再求rmax
在这里插入图片描述
继续压栈,参数位,等rmax

总结来说就是一旦它发现它执行不下去了,要等一个什么东西,那这是你的中间变量,参数位等等都会保存在系统栈里,等到算完后给它,它弹出,继续往下进行。

画递归调用图很重要!

任何递归函数都一定可以改为非递归

可以自己做个系统栈
但要注意二者的存储地方不同
系统栈压栈在系统栈空间
自己压栈在内存空间
在这里插入图片描述

递归改为非递归的必要性

工程上几乎一定要改

因为系统栈空间很贵,除非确定数据量再大递归层数也一定不深,像归并排序,快速排序,线段树,很多的平衡树等

算法鄙视或者比赛中,能通过就不改

Master公式

所有子问题规模相同的递归才能用master公式,T(n) = a*T(n/b)+0(n^c),a\b\c都是常数

在这里插入图片描述

解释一下这个公式
a*T(n/b)
假设现在我要求l到r上的最大值,一共有n个数
我要完成整个任务,我是先调用了左侧一半的数据链,给我了一个最大值。
我又调用了右侧一半的数据链,给我了一个最大值。
对于这个问题来说,b=2,a是子过程调用了几次,左边一次右边一次,所以是两次,即a=2
0(n^c)
除了子过程调用之外,这个代码里其它行为的时间复杂度是多少。
这个问题里其它的都是O(1)的,所以这个通项公式可以写成O(1)

那这道题的公式就是
T(N) = 2*T(N/2)+O(1)
即a = 2(整个子过程调用了几次),
b = 2(调用一次数据量减少了多少),
c =0(剩余过程的时间复杂度)

master公式可以直接告诉你整个过程时间复杂度是多少,结论:

如果log(b,a) < c,复杂度为:O(n^c)

如果log(b,a) > c,复杂度为:O(n^log(b,a))

如果log(b,a) == c,复杂度为:O(n^c*logn)

比如下面的问题,

给你一个数组,我想左边2/3取个最大值,右边2/3取个最大值(所以中间有重合部分),再综合求整个最大值

那么master公式即为:
在这里插入图片描述

在这里插入图片描述
所以得到abc
在这里插入图片描述
再举个例子

给你一个数组,我想左边1/2取个最大值,右边1/2取个最大值,再把整个数组都遍历打印一遍,最后综合求整个最大值

在这里插入图片描述
那么此时master公式为:

在这里插入图片描述
变动的地方就是原来其它复杂度是O(1),加上for循环后复杂度变为O(n)了,其它地方没变

所以abc即为
在这里插入图片描述
总结
master公式可以应用在子问题规模相同的递归
比如左边1/2求最大,右边1/2求最大
比如左边2/3求最大,右边2/3求最大
但是
左边1/3求最大,右边2/3求最大 不能用master公式

这样你只需要看一层就能知道整个过程的时间复杂度

一个补充:T(n) = aT(n/b)+0(nlogn),时间复杂度是O(n*((logn)的平方)),证明过程比较复杂,记住即可

http://www.dtcms.com/a/442436.html

相关文章:

  • php 怎么做 网站 图片福州外语外贸学院
  • 网站点击率东莞网站建设的公司
  • 【Linux】线程的互斥
  • 第三十九天:斐波那契数列
  • JAVA中用到的线程调度算法是什么?
  • 网站开发是无形资产如何在家里做网站
  • PySide6 打印或显示系统支持字体(QFontDataBase)
  • 网站开发框架怎么写wordpress前端会员中心开发教程
  • redis-zset数据类型的常见指令(sorted set)
  • 触摸未来2025.10.04:当神经网络拥有了内在记忆……
  • 生成对抗网络(GANs)深度解析:从原理、变体到前沿应用
  • 项目1:get_rga_thread线程和low_camera_venc_thread线程获取低分辨率VENC码流数据
  • 哪个网站做简历好musik wordpress视频
  • 【Linux】Linux管道与进程池深度解析:从原理到实战
  • Kotlin 协程之 Flow 操作符大全
  • python高级01——linux基础命令
  • 发帖那个网站好 做装修的怎么优化关键词排名优化
  • 分类信息网站建设价格西安公司注册网站
  • 数据要素X_第三批“数据要素×”典型案例——科技创新领域【附全文阅读】
  • 安装nginx时,yum 不从stable源安装
  • ui做标注的网站平面设计素材怎么找
  • 向量数据库的几个核心概念
  • 设计方案的步骤seo学习网站
  • 常熟网站制作设计长沙房产
  • 【OpenCV】图像处理入门:从基础到实战技巧
  • 站群系统破解版急切网头像在线制作图片
  • 快速排序的深入优化探讨
  • HTTP~
  • AI-调查研究-94-具身智能 机器人算法真机验证全流程解析:测试平台、部署方案与接口对接
  • leetcode 37 解数独