• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
百事可爱
一起努力鸭~~~
博客园    首页    新随笔    联系   管理    订阅  订阅
递推法与递归法

递归算法

  1. 递归算法是一种从自顶向下的算法 ,实际上是通过不停的直接调用或者间接的调用自身的函数,通过每次改变变量完成多个过程的重复计算,直到到达边界之后,结束调用。

  2. 与递推法相似的是,递归与递推都是将一个复杂过程分解为几个简单重复步骤进行计算。

  3. 实现的核心是分治策略,即分而治之,将复杂过程分解为规模较小的同类问题,通过解决若干个小问题,进而解决整个复杂问题。

  4. 递归算法设计的一般步骤:

    1. 根据题目设计递归函数中的运算部分;
    2. 根据题目找到递归公式,题目可能会隐含给出,也可能需要自己进行推导;
    3. 找到递归出口,即递归的终止条件。

    递推算法(迭代)

    1. 一个问题的求解需要大量重复计算,在已知的条件和所求问题之间总存在着某种相互联系的关系,在计算时,我们需要找到这种关系,进行计算(递推关系式)。
    2. 即递推法的关键,就是找到递推关系式,这种处理方式能够将复杂的计算过程,转化为若干步骤的简单重复运算。

例题1:

题目描述:

斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。

指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……

在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)

请求出该数列中第n个数字(n从1开始计数)是多少。

样例:

输入样例

样例输入
6
输出
8

对应的计算过程:

[0]=0
[1]=1
[2]=0+1
[3]=1+1=2
[4]=1+2=3
[5]=2+3=5
[6]=5+3=8

题目解析:

  1. 递归式,F(n)= F(n-1) + F(n-2)

  2. F(n)=0 n=0 ,F(n)=1 n=1 这就是递归出口,能让递归停止的条件。

递推法实现:

import java.util.Scanner;
public class Main {

    public static void main(String[] args) {
        int n; //第几个数
        int x=0; //F(n)
        int y=1; //F(n+1)
        int ans = 0; //F(n+2)
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        if(n==0) ans=0;
        else if(n==1) ans=1;
        else {
            for(int i=2;i<=n;i++)
            {
                ans=x+y;
                x=y;
                y=ans;
            }
        }

        System.out.println(ans);
    }
} 

递归法实现:

import java.util.Scanner;
public class Main {

    static  int fn(int n)
    {
        if(n==0)
            return 0;
            //递归出口2
        else if(n==1 )
            return 1;

        else
            return fn(n-1)+fn(n-2); //递归关系式
    }

    public static void main(String[] args) {
        int n; //第几个数
        int ans = 0;
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        ans=fn(n);       
        System.out.println(ans);
    }
}

例题2: (题目分存储和非存储的,若是需要多次询问数据,就采取存储的方式)

题目描述:

这样一个数列:0、1、1、2、3、5、8、13、21、34、……

在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)。

我们将进行M次查询,每次输入一个N,其中n小于30。

请求出该数列中第n个数字(n从1开始计数)是多少?

样例:

输入样例

样例1输入:

6
4
2
7
8
8
10
输出样例

样例1输出:

3
1
13
21
21
55

题目解析:

这道题跟上面一道题的算法原理相同,只是增加了多次查询的复杂度;

将每次访问的结果都保存在数组中,数组的下标正好与n对应起来

数组的长度就是n的取值范围;

递推法实现:

import java.util.Scanner;

public class DiGui1 {
	
	//将每次访问的结果都保存在数组中,数组的下标正好与n对应起来
	static int[] result = new int[35];
	
	//实现每次计算
	static void danci() {
		result[0] = 0;
		result[1] = 1;
		for(int i=2;i<=30;i++) {
			result[i] = result[i-1] + result[i-2];
		}
	}
	public static void main(String[] args) {
		 
		Scanner scanner  = new Scanner(System.in);		
		int m = scanner.nextInt();//m次的查询
		
		danci(); //因为此函数不需要传参数,运行一次,就将n从0到30的结果都保存到结果数组中,所以写到每次循环的外面
		
		//查询m次
		while(m>0) {
			m--;
			//要查询的值对应的n,在循环体内输入
			int n = scanner.nextInt();
			System.out.println(result[n]);
			 
		}
	}
}

递归法实现:

import java.util.Scanner;

public class DiGui2 {

	// 将每次访问的结果都保存在数组中,数组的下标正好与n对应起来
	static int[] result = new int[35];

	// 实现每次计算
	static int danci(int n) {
		// 递归出口1
		if (n == 0) {
			result[0] = 0;
			return 0;
		} else if (n == 1) {
			result[1] = 1;
			return 1;
		} else {
			result[n] = danci(n - 1) + danci(n - 2);
			return result[n];
		}
	}

	public static void main(String[] args) {

		Scanner scanner = new Scanner(System.in);
		int m = scanner.nextInt();// m次的查询
		// 因为递归底层运算是从n=0 一直到n=30,运行一次,就将n从0到30的结果都保存到结果数组中,所以写到每次循环的外面
		danci(30);
		// 查询m次
		while (m > 0) {
			m--;
			// 要查询的值对应的n,在循环体内输入
			int n = scanner.nextInt();
			System.out.println(result[n]);
		}
	}
}

总结:

对于以上两种方式实现存储型的递推与递归,都是先把各个结果得出,存储到数组中保存起来,那多次访问,就不用每次都计算一下。

posted on 2022-03-25 21:25  精致猪猪侠  阅读(576)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3