&递归&

基本思想是某个函数直接或者间接地调用自身,这样原问题的求解就转换为了许多性质相同但是规模更小的子问题。求解时只需要关注如何把原问题划分成符合条件的子问题,而不需要过分关注这个子问题是如何被解决的。

<特点>

结构清晰,可读性强。

代码特点

结束条件和自我调用。自我调用是在解决子问题,而结束条件定义了最简子问题的答案。

<缺点>

利用堆栈来实现的。每当进入一个函数调用,栈就会增加一层栈帧,每次函数返回,栈就会减少一层栈帧。而栈不是无限大的,当递归层数过多时,就会造成 栈溢出 的后果。

&题目A&(经典递归法解题)

求两个数的最大公约数

<>

<代码实现>

 import java.util.Scanner;
public class Main{
public static void main(String[]ages)
{
    Scanner input=new Scanner(System.in);
    int m=input.nextInt();
    int n= input.nextInt();
    god(m,n);
    System.out.println(god(m,n));
}
public static int god(int m,int n)
{
    if(m==n)
    {
        return m;
    }
    if(m>n)
    {
        return god(m-n,n);
    }
    else{
        return god(n,m);
    }
  }

}

<方法:递归方法求数位之和>

&题目B:振兴中华&

小明参加了学校的趣味运动会,其中一个项目是跳格子,地面上画着一些格子,每个格子里写一个字,如下图所示

从我做起振

我做起振兴

做起振兴中

起振兴中华

比赛是先站在左上角的写着从字的格子里,可以横向或者纵向跳到相邻的格子里,但不能跳在对角的格子里,或其他的位置,一直要跳到华字结束

要求跳过的路线刚好构成“从我做起振兴中华”这句话

请你帮助小明算一算他一共有多少种路线。

<解题方法:递归类比与深度搜索DFS>

<代码实现>

 //递归需要考虑的问题:重复,变化,边界

 import java.util.Scanner;
 public class Main {
public static void main(String[] args) {
    Scanner input=new Scanner(System.in);
    int ans=f(0,0);
    System.out.println(ans);
}
public static int f(int i,int j)
{
    if(i==3||j==4)
    {
        return 1;
    }
    else{
        return f(i+1,j)+f(i,j+1);
    }
}
  }

&题目B&<递归法计算行列式的值>

给定一个N×N的矩阵A,求|A|。

<代码实现>

 import java.util.Scanner;
  public class Main {
public static void main(String[] args) {
    Scanner input=new Scanner(System.in);
    int n= input.nextInt();
    int [][]ant=new int[n][n];
    for(int i=0;i<ant.length;i++)
    {
        for(int j=0;j<ant[i].length;j++)
        {
            ant[i][j]= input.nextInt();
        }
    }
    hls(ant);
    System.out.println(hls(ant));

}
public static int hls(int [][]ant)
{
    int res=1;
    for(int i=0;i< ant.length;i++)
    {
        for(int j=i+1;j<ant[i].length;j++)
        {
            
                int div=ant[i][i]/ant[j][i];
                for(int  k=i;k< ant.length;k++)
                {
                    ant[i][k]=ant[i][k]-div*ant[j][k];
                    int temp=ant[i][k];
                    ant[i][k]=ant[j][k];
                    ant[j][k]=temp;
                }
        }
        res=res*ant[i][i];
    }
    return res;
}

}

&题目c&

把1~n这n个整数排成一行后随机打乱顺序输出所有可能的顺序
 import java.util.Scanner;
 public class Main {
public static java.io.PrintWriter out = new java.io.PrintWriter(System.out);
public static void main(String[] args) {
    Scanner input=new Scanner(System.in);
    int n= input.nextInt();
    int []a=new int[n];
    boolean[]ant=new boolean[n];
    dg(a,ant,0,n);
    input.close();
    System.out.flush();
    System.out.close();
}
public static void dg(int []a,boolean[]vis,int i,int n)
{
    if(i==n)
    {
        for(int j=0;j<a.length;j++)
        {
            System.out.print(a[j]+" ");
        }
        System.out.println();
        return;
    }
    for(int j=0;j<n;j++)
    {
        if(!vis[j])
        {
            a[i]=j+1;
            vis[j]=true;
            dg(a,vis,i+1,n);//递归调用
            vis[j]=false;
        }
    }
}

}