递归函数设计技巧

news/2024/10/5 9:46:54/

目录

1.路飞吃桃子的问题--应试难度

2.弹簧板问题--应试难度

3.递归实现指数型枚举--校招难度

4.递归实现组合型枚举--校招难度

5.递归实现排列型枚举--校招难度


1.路飞吃桃子的问题--应试难度

我们可以说下两个案例,反正是最后一天的时候,只剩下了一个桃子,因此如果我们输入的这个天数是2,这个时候就是4个,这个是怎么计算的呢?

就是我们原来的这个桃子的数量是x,这个时候一天之后就是x除以2-1,这个就是剩下的桃子的数量,因此我们想要倒退回去,根据这个数学表达式,应该就是加上1然后乘上2,我们的这个最后的数量是1,加上1乘以2就是4个;

同理,我们在看一下3天的桃子数量,上面是4,(4+1)*2=10个,这个就是第三天的数量; 

根据上面的这个思路,我们进行这个代码的编写,首先这个fn就是我们的保证吃n天的这个桃子的数量,当n=2的时候,这个时候我们应该输出的就是4,因为我们的输入为2天,这个第二天就是最后一天,这个时候就剩下了一个;

我们的f(n-1)就是能够n-1天吃的这个桃子的数量,这个时候根据上面的的那个数学关系,fn=(f(n-1)+1)*2这个数量,最后就可以去设计递归函数了;

2.弹簧板问题--应试难度

下面的这个就是弹簧板问题的题目描述:

下面的这个就是上面题目的案例,我们可以通过案例帮助我们更好地理解这个弹簧板的设计的过程,就是这个小球具体是怎么搞的,怎么弹出去的,下面的第一个样例输入里面,我们的这个5表示的是有5个节点的数据,第一个2表示从这个位置开始的时候,我们会弹出2个位置,这个时候就到了第三个数字3这个位置,3表示的就是到达这个地方之后,我们向后弹出去3个位置,这个时候就会直接弹出去了,因此这个过程就是只需要弹2次,就可以弹出这个弹簧板了;

下面的这个就是递归函数的设计思路:
这个i表示的就是这个数组的下标,我们的上面输入5的时候不是有5个数据吗,这个就是一个数组,我们把输入的这个数组当做一个下标;

i>n(第一次输入的数字)的时候,这个时候可不就已经跳出去这个弹簧板了吗,这个就是我们的递归的临界条件;

fi表示的就是第i个下标的这个板子,fi+a[i]表示的从这个板子开始弹出a[i]之后的这个位置,为什么是加上1呢,因为这个只需要跳一次啊;

按照上面的这个设计思路,我们进行下面的这个代码的编写,这个代码是使用的C++进行编写的,这个里面用到了vector对于我们输入的数据进行存储,我们每输入一个数据,这个数据就会被push_back到我们的这个数组里面去,同时这个n作为循环的控制条件判断我们的这个输入是不是结束了;

在f这个函数里面,我们使用引用进行接收,这个可以减少一次数组的拷贝,然后就是这个递归函数的实现,n表示的就是我们的数组元素的个数,vector<int>表示的就是我们的这个容器里面都是int类型的数据;

3.递归实现指数型枚举--校招难度

我们的这个递归函数里面是有三个参数,第一个就是i表示的就是在第i个位置填写数据,j表示的就是这个位置填写的最小的数据,n表示的就是这个位置填写的最大的数据;

第三步就是怎么让这个程序走通,我们使用的方法就是f(i,j,n)=j+f(i+1,j+1,n)就是我们的第i个位置填上这个数字j之后,我们的下一位置只能填写数字j+1了;

print_one_result就是对于这个数组输出的结果进行打印;

4.递归实现组合型枚举--校招难度

这个题目其实和上面的没有很大的区别,主要就是这个题目限制我们输出的数字的数量,我们输入的两个参数里面有一个参数控制我们输出的数量,但是大部分都是一样的;

这个里面的递归函数,我们设置了4个参数,前面的三个参数的含义不变,其中这个里面的第四个参数表示的就是我们的输出的个数,就是每一次输出是几个数字,在上面的这个案例里面,样例1输出的是每一次都有2个,样例2输出的是每一次都有3个;

我们的代码里面的四个参数如main函数所示,其中这个里面还是有一个print_one函数负责对于这个数据的打印;

f递归函数,首先判断我们的这个终止条件:当我们的这个i==m就是我们的这个数字的个数等于要输出的这个数字的个数的时候,我们就会直接进行return语句,因为这个第一次的时候这个i=0,然后进入这个for循环里面进行第一次递归的时候,这个i就是1了,以此类推我们的这个i==m说明我们的这个输出的数据已经够了,这个时候就会停止输出;

但是我们的第i个位置的数据不可以太大,因为如果我们的这个数据最大就是5,然后我们的这个第i个数字就是5的话,这个时候后面就没有数据可以放置(因为这个数据是按照递增顺序进行排序的),所以我们的这个n-k(数据的个数)>=m-i-1(可以放置数据的空间容量的大小);当然这个就是提高代码的效率,不放也是可以的,只写一个k<=n也是可以正常输出结果的,加上上面的这个就是对于我们的这个输出进行优化罢了;

5.递归实现排列型枚举--校招难度

下面的这个就是实现的我们的排列型枚举,这个枚举和上面的区别就是我们的这个枚举的过程,可以是不按照一个递增的顺序进行排列,就是我们的这个后面的数字的大小可以小于前面的数字;

这个时候,我们的思路就稍稍有了一些变化,我们定义一个新的viso数组,这个数组里面的数据全部都是0,1,其中这个里面的1表示这个位置的数据已经被使用过了,我们这个时候就不可以使用这个数据了,如果这个位置的数据是0,表示这个数据没有被使用,我们可以使用这个数据进行填写

下面的这个代码就是按照上面的这个思路进行编写的,print用来进行每一组数据的打印输出控制,和之前的两道题目都是一样的;

f函数里面的首先就是一个if分支语句,这个语句就是判断我们的这个数组里面的元素是不是凑成了一组数据,如果是等于n说明这个就是一组数据,我们直接调用这个print函数进行打印即可;

如果不是的话,我们就要使用下面的这个for循环进行判断,这个for循环里面就会用到我们的上面的这个viso这个数组,因为我们刚开始的时候定义这个数组全部初始化为0,表示这个数组里面的元素没有被使用过,viso[k]不为0,这个时候,说明这个数字就被使用过,我们这个时候直接continue跳过这个数字;

否则,这个数组这个位置的元素就是0,没有被使用过,我们就要向这个数组里面填数据,arr[i]=k表示把这个没有用过的数据填充到k下标的位置,用过之后这个viso[k]就要置为1,表示这个已经被用过了,然后就是填充这个i+1位置,进行递归,下面的这个viso[k]=0表示这个数字又没有使用过了;

这个是什么意思呢,因为我们上面的这个f(i+1,n)不断地进行递归之后,我们的这个已经全部使用了一遍,例如,我们上面的这个是123   132这种,这个时候,我们的1开头的已经全部列举完成了,因此我们需要已2开头进行列举,这个时候,我们之前的这个所有的标记就是需要清零,重新以2作为起始数据开始列举,因此这个viso[k]=0相当于就是清空之前的操作,开始新一轮的列举(这个很重要!!!);

为什么这个循环里面的k从1开始,而且终止条件是k<=n呢,这个开始我也不是很理解,后来发现,其实这个k表示的根本不是下标,而是我们的数据,例如我们输入的这个数据是5,这个k循环的时候就是1,2,3,4,5这个k就是从1开始的,表示的最大的数据就是我们的输入的n的数值;

反正这个for循环里面的内容不是很好理解。思路很清理,具体如何去进行实现还是需要我们多去揣摩的~~


http://www.ppmy.cn/news/1533823.html

相关文章

RabbitMQ的各类工作模式介绍

简单模式 P: ⽣产者, 也就是要发送消息的程序 C: 消费者,消息的接收者 Queue: 消息队列, 图中⻩⾊背景部分. 类似⼀个邮箱, 可以缓存消息; ⽣产者向其中投递消息, 消费者从其中取出消息.特点: ⼀个⽣产者P&#xff0c;⼀个消费者C, 消息只能被消费⼀次. 也称为点对点(Point-to-…

【深度学习】05-RNN循环神经网络-02- RNN循环神经网络的发展历史与演化趋势/LSTM/GRU/Transformer

RNN网络的发展历史与演化趋势 RNN&#xff08;Recurrent Neural Network&#xff0c;循环神经网络&#xff09;是一类用于处理序列数据的神经网络&#xff0c;特别擅长捕捉数据的时间或上下文依赖性。在其发展的过程中&#xff0c;不断出现各种改进和变体&#xff0c;以解决不…

【零基础入门产品经理】学习准备篇 | 需要学一些什么呢?

前言&#xff1a; 零实习转行产品经理经验分享01-学习准备篇_哔哩哔哩_bilibili 该篇内容主要是对bilibili这个视频的观后笔记~谢谢美丽滴up主友情分享。 全文摘要&#xff1a;如何在0实习且没有任何产品相关经验下&#xff0c;如何上岸产品经理~ 目录 一、想清楚为什么…

Mac 电脑配置yolov8运行环境实现目标追踪、计数、画出轨迹、多线程

&#x1f947; 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 &#x1f389; 声明: 作为全网 AI 领域 干货最多的博主之一&#xff0c;❤️ 不负光阴不负卿 ❤️ 文章目录 &#x1f4d9; Mac 电脑 配置 yolov8 环境&#x1f4d9; 代码运行推理测试模型训…

【蚂蚁HR-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

Systemctl

目录 事件起因&#xff1a; 一、Systemctl是什么 1、Systemd是什么 解决&#xff1a; 事件起因&#xff1a; 使用systemctl restart mysql 重启mysql之后发现mysql修改的配置文件的内容没有应用上&#xff0c;故而研究原因。 一、Systemctl是什么 Systemctl是一个system…

微服务--SpringAMQP

AMQP&#xff1a;高级消息队列协议&#xff0c;是应用程序之间传递业务消息的开放标准&#xff0c;与语言和平台无关&#xff0c;更符合微服务架构中独立性的要求。 SpringAMQP&#xff1a;基于AMQP协议定义的一套API规范&#xff0c;提供了模板来发送和接收消息。它包含两部分…

Linux防火墙配置绿色端口,解决无法访问java服务的问题

配置防火墙&#xff0c;添加或删除端口&#xff0c;需要有root权限。 防火墙常用命令如下&#xff1a; 1.查看防火墙状态&#xff1a; systemctl status firewalldactive(running)&#xff1a;开启状态&#xff0c;正在运行中 inactive(dead)&#xff1a;关闭状态&#xff0…