递归数列相关知识
-
Python yield 使用浅析您可能听说过,带有 yield 的函数在 Python 中被称之为 generator(生成器),何谓 generator ?我们先抛开 generator,以一个常见的编程题目来展示 yield 的概念。如何生成斐波那契數列斐波那契(Fibonacci)數列是一个非常简单的递归数列,除第一个和第二个数外,任意一个数都可由前两个数相加得到。用计算机程序输出斐波那契數列的前 N 个数是一个非常简单的问题,许多初学者都可以轻易写出如下函数:清单 1. 简单输出斐波那契數列前 N 个数def fab(max): n, a, b = 0, 0, 1 while n < max: print b &nb
-
递归与伪递归区别,Python 实现递归与尾递归递归函数在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。(1) 递归就是在过程或函数里调用自身。(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。递归一般用于解决三类问题: (1)数据的定义是按递归定义的。(n的阶乘) (2)问题解法按递归实现。(回溯) (3)数据的结构形式是按递归定义的。(二叉树的遍历,图的搜索)递归的缺点: 递归解题相对常用的算法如普通循环等,运行效率较低。因此,应该尽量避免使用递归,除非没有更好的算法或者某种特定情况,递归更为适合的时候。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储,因此递归次数过多容易造成栈溢出。#递归函数 act(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x ndef fact(n):if n==1:return 1return n*fact(n-1)尾递归是指,在函数返回的时候,
-
Python3之递归函数简单示例概述 递归函数即直接或间接调用自身的函数,且递归过程中必须有一个明确的递归结束条件,称为递归出口。递归极其强大一点就是能够遍历任意的,不可预知的程序的结构,比如遍历复杂的嵌套列表。 递归求和 我们可以利用递归函数实现一个Python内置函数sum()的递归版。 # 递归 def d_sum(L): if not L: return 0 else: return L[0] + d_sum(L[1:]) sum_l = d_sum(range(10)) print(sum_l) 示例结果 45 该递归函数怎么实现列表元素相加的呢? 我们知道函数是有本地作用域的
-
python--递归(附利用栈和队列模拟递归)一、递归递归调用:一个函数,调用的自身,称为递归调用递归函数:一个可以调用自身的函数称为递归函数 凡是循环能干的事,递归都能干?1234方法:1、写出临界条件2、找这一次和上一次的关系3、假设当前函数已经能用,调用自身计算上一次的结果再求出本次的结果 下面我们通过两段代码简单看一下递归和非递归的区别: 输入一个大于等于1的数,求1到n的和!1 # 普通函数方法2 3 def hanshu(n):4 sum = 05 # 循环遍历每一个数字,将他们加到一个事先定义好的变量上,直到加完6 for x in range(1, n+1):7 &nb
递归数列相关课程
递归数列相关教程
- 3. 用递归方法求解斐波那契数列 在这一节中,我们就需要利用递归的思想去求解斐波那契数列,当给出一个斐波那契中第几项的数字,然后求解出对应的斐波那契数值。在之前,我们已经定义了递归算法的相关概念,并且明确了需要应用递归时候的三要素:递归终止条件;递归终止时候的处理方法;递归中重复的逻辑提取,缩小问题规模。接下来,我们将利用递归的知识来解决斐波那契数列问题,明确在斐波那契数列求解问题中的递归三要素分别是什么。斐波那契数列的递归终止条件显然易见,通过观察斐波那契数列的定义,我们很容易发现当 n=1 或者 n=2 时,是斐波那契数列的递归终止条件,这个时候可以给出斐波那契数列的具体值。斐波那契数列递归终止时候的处理方法同样的,基于斐波那契数列的递推定义,当斐波那契数列达到终止条件 n=1 或者 n=2 时,我们也很容易发现对应 F(1)=1,F(2)=1,这就是斐波那契数列在递归终止时对应的取值。斐波那契数列的递归重复逻辑提取按照斐波那契数列的数学定义,F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*),即当 n ≥ 3 时,斐波那契数列中这一项的值等于前面两项的值之和,这样便可以将求解一个比较大的斐波那契数列转化为求解较小数值的斐波那契数列值,这里面有重复逻辑可以递归复用。例如,当我们求解斐波那契数列中的 F(5) 时,按照定义,我们有:F(5) = F(4) + F(3) // 递归分解 = ( F(3) + F(2) ) + ( F(2)+F(1) ) // 递归求解 = [ ( F(2)+F(1) ) + 1 ] + ( 1+1 ) // 递归求解,遇到终止条件就求解 = [(1+1) +1 ]+(1+1) // 归并 = 3 + 2 // 归并 = 5 // 归并
- 2.5 递归函数 Shell 支持递归函数,递归函数也就是自己调用自己,即在函数体内部又一次调用函数自己,例如:[root@master func]# cat recursion.sh #!/bin/bashfunction myecho() { echo "$(date)" sleep 1 myecho inner}myecho[root@master func]# bash recursion.sh Sat Mar 28 13:14:38 CST 2020Sat Mar 28 13:14:39 CST 2020Sat Mar 28 13:14:40 CST 2020Sat Mar 28 13:14:41 CST 2020Sat Mar 28 13:14:42 CST 2020...如上就是一个递归函数,在函数体内部又调用了函数 myecho,在执行的时候就会陷入无限循环。
- 3. 用数学归纳法理解递归思想 很多时候,大家都在思考递归在数学上面应该如何表示了,毕竟对于数学的简单理解比起我们直接写代码起来还是要简单很多的。观察递归,我们会很容易发现递归的数学模型类似于数学归纳法,这个在高中的数列里面就已经开始应用了。数学归纳法常见的描述如下最简单和常见的数学归纳法是证明当 n 等于任意一个自然数时某命题成立。证明分下面两步:证明当 n= 1 时命题成立。假设 n=m 时命题成立,那么可以 推导出在 n=m+1 时命题也成立。(m 代表任意自然数)数学归纳法适用于将需要解决的原问题转换为解决他的子问题,而其中的子问题又可以变成子问题的子问题,而且这些问题都是同一个模型,可以用相同的处理逻辑归纳处理。当然有一个是例外的,就是归纳结束的那一个处理方法不能适用于其他的归纳处理项。递归同样的是将大的问题分解成小问题处理,然后会有一个递归的终止条件,满足终止条件之后开始回归。数学里面有一个很有名的斐波那契数列,我们在编程求解斐波那契数列的时候就会用到递归的思想,在后续的内部中会具体讲到。
- 3. 递归穷举 我们来看 leetcode 的第 15 题:三数之和。该题的难度为中等,题目内容如下:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。**注意:**答案中不可以包含重复的三元组。示例:给定数组 nums = [-1, 0, 1, 2, -1, -4],满足要求的三元组集合为:[ [-1, 0, 1], [-1, -1, 2]]我们今天并不打算通过这道题的题解,因为这道题用递归算法是无法通过题解的,原因和之前一样,算法的时间复杂度高,最后会超出时间限制。另外我们去掉后面的注意部分事项,允许答案包含重复的三元组,我们使用递归算法相当于穷举出所有可能的情况,判断三元组的值是否能为 0。首先继续我们的解题三部曲:函数定义,输入和输出:def three_sum(nums, target, count): """ 输入: num: 输入的数组 target: 目标值 count: 在数组中找到几个数之和满足target 输出: []或者[[1,2,3], [-1,4,3]] 这样的满足条件的全部结果 """ res = [] # ... return res注意: 定义这样的递归函数是经过思考的,因为后续递归调用时需要依赖目标值 (target) 或元素个数 (count) 这样两个参数。返回的参数要么为空,要么是所有找到的满足条件的三元组的集合。接下来是递归方法的终止条件,首先考虑以下几个终止条件:如果输入的 nums 列表为空,那么直接返回 [];如果输入的 count 等于1,就要开始判断了,因为这个时候只需要判断 target 是否在列表中存在即可;综上,我们写出终止条件的代码:def three_sum(nums, target, count): """ 输入: num: 输入的数组 target: 目标值 count: 在数组中找到几个数之和满足target 输出: []或者[[1,2,3], [-1,4,3]] 这样的满足条件的全部结果 """ res = [] ###################### 终止条件 ###################################### if not nums: return res if count == 1 and target in nums: return [[ target ]] elif count == 1 and target not in nums: # count等于1时,如果target没有出现在剩余的nums中,说明不存在满足条件的数组元素 return res ####################################################################### # 返回值 return res接下来最重要的,就是递归的公式了,递归的方向一定要朝着减小目标函数规模进行。很明显,我们的递归应该是这样子:以 nums 的第一个元素为递归点,整个 nums 列表中和为 target 的 count 个元素的结果可以分为包含 nums[0] 和不包含 nums[0] 的结果组成,简单点说就是:如果包含 nums[0],那么接下来的 nums[1:] 列表中我们就要找值为 target - nums[0] 的 count - 1 个元素,也即 three_sum(nums[1:], target - nums[0], count -1),然后我们还需要在得到的元组集中的最前面位置加上 nums[0];如果不包含 nums[0],那么就是在 nums[1:] 列表中找值为 target 的 count 个元素,用递归函数表示就是 three_sum(nums[1:], target, count);这样找到的结果正是 count 个元素。组合上述两个递归得到的结果,就得到了函数 three_sum(nums, target, count) 的结果,代码如下:res = []# 包含nums[0]t1 = three_sum(nums[1:], target - nums[0], count - 1)# 不包含nums[0]t2 = three_sum(nums[1:], target, count)if t1: for i in range(len(t1)): t = [nums[0]] t.extend(t1[i]) # 每个得到的结果前面加上 nums[0] res.append(t)if t2: for j in range(len(t2)): res.append(t2[j]) # 此时得到的res就是递归的最后结果综合就可以得到递归遍历所有三个元素和的情况并最终找出所有满足条件结果的三元集:def three_sum(nums, target, count): res = [] # 终止条件 if not nums: return res if count == 1 and target in nums: # 一定要这样写 return [[ target ]] elif count == 1 and target not in nums: return res # 包含nums[0] t1 = three_sum(nums[1:], target - nums[0], count - 1) # 不包含nums[0] t2 = three_sum(nums[1:], target, count) if t1: for i in range(len(t1)): # 犯了一个巨大的错误,extend() 方法的使用,它无返回,只会扩充原数组 # res.append([nums[0]].extend(t1[i])) t = [nums[0]] t.extend(t1[i]) res.append(t) if t2: for j in range(len(t2)): res.append(t2[j]) return res调用该函数的方式如下:nums = [-1, 0, 1, 2, -1, -4]# 0 为目标值,3为多少个元素和为targetres = three_sum(nums, 0, 3)这样的递归遍历思想在穷举中用的比较多,因为它以非常优雅的方式简化了穷举代码。不过这道题使用递归算法等价于穷举法,时间复杂度为 O(n3)O(n^3)O(n3),因此显得并不高效。对于最优的解法读者可以自行思考下然后解决它。
- 4. 递归的三要素 在明确递归的定义及数学模型之后,我们需要掌握递归的三要素:递归终止条件;递归终止时候的处理方法;递归中重复的逻辑提取,缩小问题规模。
- 2. 什么是递归? 递归(Recursion),是计算机科学与技术领域中一种常见的算法思想。在数学和计算机领域中,递归主要是指在函数的定义中使用函数自身的方法。顾名思义,递归主要包含两个意思,递和归,这个是递归思想的精华所在。递归就是有去(递去)有回(归来)。“有去” 是指递归问题可以分解成若干个规模较小、与原问题形式相同的子问题,这些子问题可以和原问题用相同的方法来求解。“有回” 是指这些问题的演化过程是一个从大到小,并且最终会有一个明确的终点,一旦达到终点,就可以从终点原路返回,解决原问题。更为直接的说法就是:递归的基本思想就是把大问题转化为相似的小问题解决。特别是在程序中的函数实现时,大问题的解决方案和小问题是一模一样的,所以就产生解决一个问题会调用函数本身的情况,这个也是递归的定义。
递归数列相关搜索
-
daima
damain
dart
dataset
datasource
datediff
datediff函数
datepicker
datetime
db4o
dbi
dcloud
deallocate
debian安装
debugger
debugging
declaration
declarations
declare
decode函数