《算法笔记》总结No.5——递归

一.分而治之

将原问题划分为若干个规模较小而结构与原问题相同或相似的子问题,然后分别解决这些子问题,最后合并子问题的解,即可得到原问题的解,步骤抽象如下:

  1. 分解:将原问题分解为若干子问题
  2. 解决:递归求解所有子问题,如果子问题的规模小到可以直接解决,就直接解决它
  3. 合并:将子问题的解合并为原问题的解

子问题之间应该是相互独立且没有交叉的,从严格的定义上将,子问题个数为1的情况称为减治,而大于1的情况称为分治。

分治法作为一种思想,即可使用递归的手段去实现,也可以通过非递归的手段去实现。

二.递归

递归的一个很符合精髓且搞笑的定义:要理解递归,你要先理解递归,直到你能理解递归为止

递归的核心在于——反复调用自身函数,但是每次能把问题范围缩小,直到范围缩小到可以直接得到边界数据的结果,然后再在返回的路上求出对应的解。

两个重要概念:

  • 递归边界:分解问题的尽头
  • 递归式(或者称之为递归调用、递归函数):分解子问题的手段

        如果使用递归而式而不进行阻止,那么最后将会无法停止这个黑洞似的无穷尽的算法。递归的代码结构中移动存在上述两个概念,他们支撑起了整个递归最关键的逻辑。

三.递归计算阶乘

直接先上代码:

#include <iostream>
using namespace std;int F(int n){if(n==0) return 1;elsereturn F(n-1)*n;
}int main() {int n=0;cin>>n;cout<<F(n);return 0; 
}

仔细观察,不难发现:

  • 递归边界:n==0
  • 递归式:F(n-1)*n

来仔细的分析一下,对于F(5)来说——相当于是F(4)*5,以此类推,直接将F(5)分解到了F(0),此时F(0)=1,即子问题的答案,再将所有子问题的答案合并,即可完成本次求解~

假设输入的是3,则推倒过程依次为:

  • F(3)
  • F(2)*3
  • F(1)*2*3
  • F(0)*1*2*3
  • 得到最后的F(0)的值以后,再返回去依次计算F(1)、F(2)、F(3)

四.递归计算裴波那契数列

#include <iostream>
using namespace std;int F(int n){if(n==0||n==1) return 1;elsereturn F(n-1)+F(n-2);
}int main() {int n=0;cin>>n;cout<<F(n);return 0; 
}

仔细观察,也没什么难度:

  • 递归边界:0和1的返回值均为1
  • 递归式:根据定义,第三项开始即为前两项的和

        对于这类递归问题,只要找到了递归边界和递归式,写起来代码就没什么难度。递归边界用来返回最简单底层的结果,递归式用来减小规模并进一步向下一层递归。递归图可以将递归放在一个平面上思考,有利于更快分析题目~

五.全排列

        某种意义上来说,学会递归的思维正是从一个只会暴力的小白蜕变的过程,比如当我们要求输入1~n之间数的全排列,如果硬碰硬直接霸王硬上弓,这个复杂度简直不能想象——毕竟光数量都达到n的阶乘个,何况找起来也是很费事的。

        从递归的角度去考虑,如果把问题描述成“1~n这n个整数的全排列”,那么就可以拆分为若干个子问题:“输出以1开头的全排列”、“输出以2开头的全排列”……以此类推。不妨设置一个数组P,用来存放当前的排列;再设置一个散列数组hashTable,其中hashTable[x]当x已在P中时赋值为true。

        现在按照顺序往P中的第1位到第N位填入数字。不妨假设当前已经填好了1~index-1位,正准备去填写index位。我们需要枚举1~n,如果当前枚举的数字x还没哟再1~index-1中,即填入到index位,同时设置hashTable[x]为true,然后去处理index+1位;如果递归完成时,以便让P[index]填写下一个数字。

#include <cstdio>
#include <iostream> 
using namespace std;
const int maxn=11;int n,P[11],hashTable[maxn]={false};
//p为当前排列
//hashTable用来记录x是否已经在P中! void generateP(int index)  //当前处理的正是第index位 
{if(index==n+1) //1~n已经处理完了,所以相当于n+1为递归边界~ {for(int i=1;i<=n;i++)cout<<P[i];  //输出当前排列 cout<<endl;return;}for(int x=1;x<=n;x++)   //枚举1~n,试图将x填入到P[index]位上! {if(hashTable[x]==false)   //false即表示不存在~ {P[index]=x;   //填入到index位 hashTable[x]=true;  generateP(index+1);  //递归处理下一位:即index+1 hashTable[x]=false;}}
}int main() {n=3;generateP(1);return 0; 
}
  • 递归边界:index==n+1
  • 递归式:generateP(index+1);

六.N皇后问题

        N 皇后问题指的是如何将 N 个皇后放置在 N × N 的棋盘上,并且使皇后彼此之间不能相互攻击。即给你一个整数 N ,返回所有不同的 N 皇后问题的解决方案数量~

        这玩意,不知道大家有没有想起来行列式的定义:将行列式视为从矩阵的不同行和不同列中选取元素并相乘的代数和。每一项的符号由列标的逆序数决定,即如果列标的逆序数为奇数,则该项为负;若为偶数,则该项为正——其实就是全排列~不过不同的是,行列式可以在对角线上选择元素,而对于可以斜线行走的皇后,这一点显然也是不行。因此可以基于全排列的代码,然后对每一个全排列的结果进行单独判断是否存在对角线元素,即可完成~ 

 如下:判断是否在同一对角线,只需要看行距之差和列距之差的绝对值是否相同,即可:

int count=0;
void generateP(int index)  //当前处理的正是第index位 
{if(index==n+1) //1~n已经处理完了,所以相当于n+1为递归边界~ {bool flag=true;  //flag为true时表示当前为一个合法方案~ for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)if(abs(i-j)==abs(P[i]-P[j])) flag=false;   //不合法 	}if(flag)count++;return;}for(int x=1;x<=n;x++)   //枚举1~n,试图将x填入到P[index]位上! {if(hashTable[x]==false)   //false即表示不存在~ {P[index]=x;   //填入到index位 hashTable[x]=true;  generateP(index+1);  //递归处理下一位:即index+1 hashTable[x]=false;}}
}

对于递归,只要想清楚边界、递归式、问题需要的答案,就没什么难度~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/43377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用VLM训练实时计算机视觉模型

经过数十亿个参数训练的 AI 模型非常强大&#xff0c;但并不总是适合实时使用。但是&#xff0c;它们可以通过自动监督快速专用模型的标注来减少人力投入。 ‍ 如果你曾经构建过计算机视觉模型&#xff0c;就就会知道监督需要大量工作——人类花时间&#xff08;数小时或数天&a…

自动化测试全攻略:从入门到精通!

1、自动化测试专栏 随着技术的发展和工作需求的增长&#xff0c;自动化测试已成为软件质量保障体系中不可或缺的一环。 为了帮助广大测试工程师、开发者和对自动化测试感兴趣的读者们更好地掌握这一技能&#xff0c;今年特别推出了全新的《自动化测试全攻略&#xff1a;从入门…

scratch绘制四个三角形 2024年6月中国电子学会 图形化编程 scratch编程等级考试二级真题和答案解析

scratch绘制四个三角形 一、题目要求 2024年6月电子学会图形化编程Scratch等级考试二级真题 1、准备工作 1.保留默认角色小猫; 2.添加背景Stars。 2、功能实现 1 .隐藏角色小猫&#xff0c;设置画笔裙始位置为(0,0)&#xff0c;画笔颜色为黄色&#xff0c;画笔的粗细为5…

Scala Trait(特征)

Scala Trait(特征) Scala中的Trait是一种特殊的概念,它类似于Java中的接口,但提供了更多的功能。Trait允许我们定义一组方法,这些方法可以被子类实现,同时还可以包含方法的实现。这使得Trait既具有接口的灵活性,又具有抽象类的实用性。在本文中,我们将深入探讨Scala Tra…

NET Core 中的空对象设计模式

介绍 一种称为“空对象模式”的行为设计模式提供了一个对象来表示接口缺少的对象。在空对象会导致空引用异常的情况下&#xff0c;这是一种提供替代行为的方法。在本文中&#xff0c;我们将深入探讨 C# 空对象模式&#xff0c;并逐步解决更复杂的情况。 空对象设计模式它是什…

k8s离线部署芋道源码前端

目录 概述 编译Dockerfile 构建Dockerfilenginx.conf构建 k8s部署前端镜像部署ingress 概述 本篇将对 k8s离线部署芋道源码前端 进行详细的说明&#xff0c;对如何构建 Dockerfile&#xff0c;如何整合 Nginx&#xff0c;如何整合 ingress 进行实践。 相关文章&#xff1a;naco…

python 进阶教程--PIL图像处理

PIL图像处理 1. Pillow库简介2. 图像处理基础3. 图像操作4. 图像增强5. 图像处理进阶6. 图像绘制7. 图像序列和动画8. 图像识别和特征提取9. 实战项目10. 常见问题解答 1. Pillow库简介 PIL与Pillow的关系 PIL&#xff08;Python Imaging Library&#xff09;是一个提供图像处…

【云原生之kubernetes实战】在k8s环境下部署OrangeHRM人力资源管理系统

【云原生之kubernetes实战】在k8s环境下部署OrangeHRM人力资源管理系统 一、OrangeHRM介绍1.1 OrangeHRM 简介1.2 OrangeHRM特点1.3 OrangeHRM使用场景二、相关知识介绍2.1 本次实践存储介绍2.2 k8s存储介绍三、本次实践介绍3.1 本次实践简介3.2 本次环境规划3.3 部署前需准备工…

bash终端快捷键

快捷键作用ShiftCtrlC复制ShiftCtrlV粘贴CtrlAltT新建终端ShiftPgUp/PgDn终端上下翻页滚动CtrlC终止命令CtrlD关闭终端CtrlA光标移动到最开始为止CtrlE光标移动到最末尾CtrlK删除此处到末尾的所有内容CtrlU删除此处至开始的所有内容CtrlD删除当前字符CtrlH删除当前字符的前一个…

Perl 语言开发(十):正则表达式,掌握强大文本处理的利器

目录 1. 正则表达式概述 2. 基础正则表达式语法 2.1 字符和字符类 2.2 预定义字符类 2.3 量词 2.4 分组和捕获 2.5 反向引用 3. Perl 中的正则表达式操作 3.1 匹配操作 3.2 替换操作 3.3 分割操作 4. 正则表达式的高级特性 4.1 非捕获分组 4.2 前瞻和后顾 4.3 负…

Hugging face Transformers(4)—— Model

Hugging Face 是一家在 NLP 和 AI 领域具有重要影响力的科技公司&#xff0c;他们的开源工具和社区建设为NLP研究和开发提供了强大的支持。它们拥有当前最活跃、最受关注、影响力最大的 NLP 社区&#xff0c;最新最强的 NLP 模型大多在这里发布和开源。该社区也提供了丰富的教程…

【Bug优化】支付宝支付中“交易订单处理失败,请稍后再试”问题

引言 近期&#xff0c;一位友友问&#xff1a;他在集成支付宝支付功能时遇到了一个棘手的问题&#xff0c;当用户在支付过程中选择放弃支付&#xff0c;尝试重新支付同一订单时&#xff0c;前端会显示“交易订单处理失败&#xff0c;请稍后再试”。 这个问题的核心在于支…

文章SameStr(一):图1代码

“Publication Figure 1” 百度云盘链接: https://pan.baidu.com/s/15g7caZp354zIWktpnWzWhQ 提取码: 4sh7 Libraries Standard Import library(tidyverse) library(cowplot) library(scales) library(ggpubr)Special # devtools::install_github("pmartinezarbizu/…

linux 代理export

export http_proxyhttp://10.67.11.138:7890 export https_proxyhttp://10.67.11.138:7890

大/小端模式与位操作

文章目录 1. 大小端模式 2. 大端模式&#xff08;Big-endian&#xff09; 3. 小端模式&#xff08;Little Endian&#xff09; 4. 判断和转换大小端模式 5. 位操作 5.1 移位操作 5.2 取反操作 5.3 位与操作 5.4 位或操作 5.5 置位操作 5.6 清位操作 1. 大小端模式 …

大数据学习之 scala基础(补充)

scala基础&#xff1a; hello world: 写scala可运行文件的注意事项1、如果一个scala文件要运行&#xff0c;class要改成object2、如果是class&#xff0c;就仅单纯代表一个类&#xff0c;如果是object代表的是单例对象3、scala语法中&#xff0c;一句话结束不需要加分号4、sca…

Spring的AOP基础以及AOP的核心概念

2. AOP基础 学习完spring的事务管理之后&#xff0c;接下来我们进入到AOP的学习。 AOP也是spring框架的第二大核心&#xff0c;我们先来学习AOP的基础。 在AOP基础这个阶段&#xff0c;我们首先介绍一下什么是AOP&#xff0c;再通过一个快速入门程序&#xff0c;让大家快速体…

Ubuntu配置GitHub(第一次clone/push)

文章目录 1. 安装Git&检查连接2. 注册GitHub3. 生成&GitHub添加SSH3.1. 检查&删除已有id_rsa3.2. 生成SSH3.3. GitHub添加id_rsa.pub SSH3.4. 检查SSH 4. 继续开发可以参考参考 1. 安装Git&检查连接 安装 sudo apt-get install git检查SSH连接 ssh -T gitgi…

【工具分享】零零信安攻击面管理平台

文章目录 00SEC-ASM™功能介绍功能演示 最近闲来无事&#xff0c;到处网上冲浪&#xff0c;无意间发现了长亭云图攻击面管理平台&#xff0c;无奈需要授权才能使用&#xff0c;于是就找到了平替&#xff1a;零零信安攻击面管理平台。 长亭云图攻击面管理平台&#xff1a;https:…

vue2封装向上滚动组件

目录 1.代码2.使用 1.代码 <template><div class"marquee-wrap" :style"{height: height px}"><ul class"marquee-list":style"animateUpStyle"v-on:mouseover"myMouseover"v-on:mouseout"myMouseout…