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

《算法笔记》总结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;}}
}

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

相关文章:

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

一.分而治之 将原问题划分为若干个规模较小而结构与原问题相同或相似的子问题&#xff0c;然后分别解决这些子问题&#xff0c;最后合并子问题的解&#xff0c;即可得到原问题的解&#xff0c;步骤抽象如下&#xff1a; 分解&#xff1a;将原问题分解为若干子问题解决&#x…...

鸿蒙小练习

bean对象 export class BannerImage{id:numberurl:stringtargetUrl:stringproductId:numberconstructor(id: number, url: string, targetUrl: string, productId: number) {this.id idthis.url urlthis.targetUrl targetUrlthis.productId productId} }export class d…...

谷粒商城-个人笔记(集群部署篇二)

前言 ​学习视频&#xff1a;​Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强​学习文档&#xff1a; 谷粒商城-个人笔记(基础篇一)谷粒商城-个人笔记(基础篇二)谷粒商城-个人笔记(基础篇三)谷粒商城-个人笔记(高级篇一)谷粒商城-个…...

Python面试题-7

21. 请解释Python中的元组。 Python中的元组&#xff08;Tuple&#xff09;是一种内置的数据结构&#xff0c;它有如下特点&#xff1a; 有序性&#xff1a;元组中的元素是有序的&#xff0c;每个元素都有一个索引&#xff0c;索引从0开始。不可变性&#xff1a;一旦元组被创…...

微信⼩程序的电影推荐系统-计算机毕业设计源码76756

摘 要 随着互联网的普及和移动互联网的发展&#xff0c;人们对于获取信息的便捷性和高效性要求越来越高。电影作为一种受众广泛喜爱的娱乐方式&#xff0c;电影推荐系统的出现为用户提供了更加个性化和精准的电影推荐服务。微信小程序作为一种轻量级应用形式&#xff0c;在用…...

理解与解读李彦宏在2024世界人工智能大会的发言:应用优先于技术

2024年7月4日&#xff0c;世界人工智能大会暨人工智能全球治理高级别会议在上海世博中心举行。百度创始人、董事长兼首席执行官李彦宏在产业发展主论坛上提出了一个引人深思的观点&#xff1a;“大家不要卷模型&#xff0c;要卷应用&#xff01;”他强调了一个重要的观点&#…...

数字化打破传统,引领企业跨界经营与行业生态盈利

在当今数字化时代&#xff0c;传统的赚货差思路正面临着巨大的挑战。然而&#xff0c;数字化的崛起为企业提供了突破传统束缚的机会&#xff0c;促使其转向跨界经营&#xff0c;并通过行业生态经营获取利润。 首先&#xff0c;数字化打破了传统赚货差思路的局限性。以往&…...

【链表】- 链表相交

1. 对应力扣题目连接 链表相交 2. 实现思路 链表详情&#xff1a; 考虑使用双指针&#xff1a; 解法一&#xff1a; 具体代码&#xff0c;详见3. 实现案例代码解析&#xff1a; 思路&#xff1a;因为链表按照如图的箭头走向&#xff0c;走的总路程是相等的&#xff0c;一…...

【python 学习】快速了解python内置类型

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言一、内置类型的介绍1.1 类型体系1.2 空类型和None1.3 布尔值 二、内置类型的运算2.1 布尔运算2.2 比较运算符比较…...

npm ERR! code ENOTEMPTY npm ERR! syscall rename npm ERR!

报错&#xff1a; npm ERR! code ENOTEMPTY npm ERR! syscall rename npm ERR! path /home/user/.local/lib/node_modules/pkg npm ERR! dest /home/user/.local/lib/node_modules/.pkg-piikcue3 npm ERR! errno -39 npm ERR! ENOTEMPTY: directory not empty, rename ‘/home/…...

智能井盖采集装置 开启井下安全新篇章

在现代城市的脉络之下&#xff0c;错综复杂的管网系统如同城市的血管&#xff0c;默默支撑着日常生活的有序进行。而管网的监测设备大多都安装在井下&#xff0c;如何给设备供电一直是一个难题&#xff0c;选用市电供电需经过多方审批&#xff0c;选用电池供电需要更换电池包&a…...

C# AGV小车通讯开发的方法

AGV (Automated Guided Vehicle) 小车的通讯开发通常涉及与AGV控制系统或调度系统的数据交换。在C#中实现AGV小车通讯&#xff0c;可以采用多种方法&#xff0c;具体取决于AGV的通信协议和硬件接口。以下是一些常用的开发方法&#xff1a; 1. 串行通讯 (Serial Communication)…...

01-图像基础-颜色空间

1.RGB颜色空间 RGB是一种常用的颜色空间&#xff0c;比如一幅720P的图像&#xff0c;所对应的像素点个数是1280*720&#xff0c;每一个像素点由三个分量构成&#xff0c;分别是R,G,B。 R代表红色分量&#xff0c;G代表绿色分量&#xff0c;B代表蓝色分量&#xff0c;以24位色来…...

双向链表+Map实现LRU

LRU: LRU是Least Recently Used的缩写&#xff0c;即最近最少使用&#xff0c;是一种常用的页面置换算法&#xff0c;选择最近最久未使用的页面予以淘汰。 核心思想&#xff1a; 基于Map实现k-v存储&#xff0c;双向链表中使用一个虚拟头部和虚拟尾部&#xff0c;虚拟头部的…...

HTML(27)——渐变

渐变是多个颜色逐渐变化的效果&#xff0c;一般用于设置盒子模型 线性渐变 属性&#xff1a;background-image : linear-gradient( 渐变方向 颜色1 终点位置, 颜色2 终点位置, ......&#xff09;&#xff1b; 取值: 渐变方向:可选 to 方位名词角度度数 终点位置:可选 百分…...

2024上半年网络工程师考试《应用技术》试题一

阅读以下说明&#xff0c;回答问题。 【说明】 MPLS基于(1)进行转发&#xff0c;进行MPLS标签交换和报文转发的网络设备称为(2)&#xff0c;构成MPLS域(MPSDomain)。位于MPLS域边缘、连接其他网络的LSR称为(3),区域内部的LSR称为核心LSR(CoreLSR)IP报文进入MPLS网络时&#xf…...

pnpm介绍

PNPM 是一个 JavaScript 包管理器&#xff0c;类似于 npm 和 Yarn。它的全称是 "Performant npm"&#xff0c;主要设计目标是优化包的安装和管理过程&#xff0c;以提升速度和效率。PNPM 的主要特点包括&#xff1a; 符号链接&#xff08;Symlink&#xff09;&#x…...

Linux内核的启动过程(非常详细)零基础入门到精通,收藏这一篇就够了

Linux内核的生成过程 内核的生成步骤可以概括如下&#xff1a; ① 先生成 vmlinux&#xff0c;这是一个elf可执行文件。② 然后 objcopy 成 arch/i386/boot/compressed/vmlinux.bin&#xff0c;去掉了原 elf 文件中一些无用的section等信息。③ gzip 后压缩为 arch/i386/boot…...

相关分析 - 肯德尔系数

肯德尔系数&#xff08;Kendall’s Tau&#xff09;是一种非参数统计方法&#xff0c;用于衡量两个变量之间的相关性。它是由统计学家莫里斯肯德尔&#xff08;Maurice Kendall&#xff09;在1938年提出的。肯德尔系数特别适用于有序数据&#xff0c;可以用来评估两个有序变量之…...

【咨询】企业数字档案馆(室)建设方案-模版范例

导读&#xff1a;本模版来源某国有大型医药行业集团企业数字档案馆&#xff08;室&#xff09;建设方案&#xff08;一期300W、二期250W&#xff09;&#xff0c;本人作为方案的主要参与者&#xff0c;总结其中要点给大家参考。 目录 1、一级提纲总览 2、项目概述 3、总体规…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...