递归的定义:在调用一个函数的过程中又出现直接或间接调用该函数本身,称为函数的递归(Recursion)调用,这种函数称为递归函数 。若p函数定义中调用p函数,称之为直接递归。若p函数定义中调用q函数,而q函数定义中又调用p函数,称之为间接递归。

递归的两大要素:

  • 递归表达式(递归方程)
  • 递归结束条件(边界条件)

能够用递归解决的问题应该满足以下3个条件

  • 需要解决的问题可以转化为一个或多个子问题来求解,而这些子问题的求解方法与原问题完全相同,只是在数量规模上不同
  • 递归调用的次数必须是有限的
  • 必须有结束递归的条件来终止递归

 何时使用递归:

  • 定义是递归的(阶乘、斐波那契数列等)
  • 数据结构是递归的(单链表、二叉树等)
  • 问题的求解方法是递归的(汉诺塔、回溯法等)

递归的优缺点:

  • 优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便
  • 缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多
  • 解决方法:在某些递归算法中可消除递归调用,使其转化为非递归算法

 

阶乘的递归表达式:

斐波拉契数列的递归表达式:

 Kimi数列

题目描述

Kimi最近在研究一个数列: * F(0) = 7 * F(1) = 11 * F(n) = F(n-1) + F(n-2) (n≥2) Kimi称之为Kimi数列。请你帮忙确认一下数列中第n个数是否是3的倍数。

输入

输入包含多组数据。 每组数据包含一个整数n,(0≤n≤30)。

输出

对应每一组输入有一行输出。 如果F(n)是3的倍数,则输出“Yes”;否则输出“No”。

public class Main{
 
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        Scanner num=new Scanner(System.in);
        while(num.hasNext()) {
            int n=num.nextInt();
            if(func(n)%3==0) {
                System.out.println("Yes");
            }else {
                System.out.println("No");
            }
        }
        System.out.println();
     
    }
    public static int func(int n) {
     
            if(n==0) {
                return 7;
            }else if(n==1) {
                return 11;
            }else {
                return func(n-1)+func(n-2);
            }  
    }
    
}

递归计数


题目描述



编写一个递归程序,返回一个字符串中大写字母的数目。例如,输入“AbcD”,输出2。


输入

多组输入,每组包括一个仅由大小写字母组成的字符串。

输出

输出字符串中出现大写字母的数目。

样例输入 Copy

AbcD

样例输出 Copy

2

public class Main {
 
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
     int a;
     Scanner str=new Scanner(System.in);
     while(str.hasNext()) {
         String str1=str.nextLine();
         char [] c=str1.toCharArray();
         a=c.length;
         System.out.println(func(c,a-1));
     }
    }
    public static int func(char [] c,int x) {
        if(x==-1) {
            return 0;
        }else {
            if(c[x]>='A'&&c[x]<='Z') {
                return 1+func(c,x-1);
            }else {
                return func(c,x-1);
            }
        }  
    }
}

蜂房 问题

题目描述

有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。
其中,蜂房的结构如下所示。

 

实现Digest_自动生成



输入

多组数据输入,每组数据包含两个正整数a, b,且 a<b。

输出

蜜蜂从蜂房a爬到蜂房b的可能路线数。

样例输入 Copy

1 2 3 4

样例输出 Copy

1 1

public class Main  {
 
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
      Scanner input=new Scanner(System.in);
      while(input.hasNext()){
         int a=input.nextInt();
         int b=input.nextInt();
         System.out.println(func(a,b));
 }
       
 }
 
    public static int func(int x,int y){
        if(x==(y-1)){
          return 1;
    }
        else if(x==(y-2)){
          return 2;
    }
        else return func(x,y-1)+func(x,y-2);
         
    }
 }

逆序输出 

题目描述

使用递归编写一个程序,逆序输出一个非负整数。例如输入1234,输出4321(不含前导0)。

输入

多组输入,每组输入一个非负整数。

输出

逆序输出结果,每个结果占一行。

样例输入 Copy

12 1230 0

样例输出 Copy

21 321 0

public class Main {
    public static int func(int n){
        if(n >= 10){
            System.out.print(n%10);
            n = n/10;
            return func(n);
        }else {
            return n%10;
        }
    }
 
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            while (input.hasNext()){
               int n = input.nextInt();
            if(n==0){
                System.out.println(n);
                continue;
            } else if(n > 0){
                while(n%10==0){
                    n = n/10;
                }
                System.out.println(func(n));
            }
                    }
    }
  
}

骨牌覆盖 

题目描述

用大小为1×2的骨牌铺满一个大小为2×n的长方形方格,编写一个程序,输入n,输出铺放方案总数。例如,输入n=3,即大小为2×3的方格,输出3。3种骨牌铺放方案如下图所示:

实现Digest_实现Digest_02


输入

多组测试用例,每一组是一个正整数。

输出

每组输出占一行。
只需要输出铺放方案总数,不需要输出具体的铺放方案。

样例输入 Copy

3

样例输出 Copy

3

 

public class Main {
 
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
     Scanner num=new Scanner(System.in);
     while(num.hasNext()) {
         int n=num.nextInt();
         System.out.println(function(n));
          
     }
    }
   public static int function(int n) {
       if(n==1) {
           return 1;
       }else if(n==2) {
           return 2;
       }else {
           return function(n-1)+function(n-2);
       }
   }
}