算法学习,递归问题汇总:求 n的阶乘,斐波那契数列,台阶问题,计算n条直线最多能把平面分成多少部分,猴子吃桃问题,女朋友问你在第几排电影院太黑无法看清

6/11
1.求 n的阶乘

    public static int result(int n){
        //递归出口
        if(n==1)
            return 1;//1的阶乘就等于1
        return n*result(n-1);

2.斐波那契数列(不死神兔)

	//递归返回斐波那契数列
public static int fibonacci(int n){
        if(n==1||n==2)
            return 1;
        return fibonacci(n-1)+fibonacci(n-2);
    }
    //用循环求解斐波那契数列
    public static int fibonacci2(int n){
        int[] result=new int[n+1];
        for(int i=1;i<=n;i++){
            if(i==1||i==2)
                result[i]=1;
            else
                result[i]=result[i-1]+result[i-2];
        }
        return result[n];
    }

3.台阶问题
一个楼梯有n (n >= 1)级,每次走1级或两级,
// 请问从1级台阶走到第n级台阶一共有多少种走法(假设一开始站在第0级台阶上)

  • 1级台阶,走一步,只有一种走法
  • 2级台阶,走一步,走两步,两种走法
  • 3级台阶,1+1+1,2+1,1+1,三种走法
  • …… ……
 public static int fun(int n) {

        if(n == 1)
            return 1;
        if(n == 2)
            return 2;
        return (fun(n-1)+fun(n-2));
    }

4.计算n条直线最多能把平面分成多少部分?
n >= 1

  • 最大划分平面的情况是和画的下一条线和之前所画所有线都相交的情况
  • 与多少条线相交就增加多少区域+1
    线条数 区域数
  •   1           2
      2           4
      3           7
      4           11
     ……           ……
      n           f(n-1)+n
    
public class Work02 {
    public static void main(String[] args) {
        int n=4;
        System.out.println(n+"条直线最多能把平面分成"+result(n)+"份");
    }
    public static int result(int i){
        if(i==1)
            return 2;
        return result(i-1)+i;
    }
}

5.猴子吃桃问题
猴子第一天摘了若干个桃子,当即吃了一半,还不解馋,又多吃了一个;
第二天,吃剩下的桃子的一半,还不过瘾,又多吃了一个;
以后每天都吃前一天剩下的一半多一个,到第10天想再吃时,只剩下一个桃子了。
问第i(i的取值范围为[1, 10])天的桃子个数?

public class Work03 {
    public static void main(String[] args) {
        System.out.println("用循环");
        peachA();
        System.out.println("用递归,第一天有" + peachB(1) + "个桃子");

    }
    //递归
    public static int peachB(int i) {//i 天
        if (i == 10)
            return 1;
        return (peachB(i + 1) + 1) * 2;
    }
	//循环
    public static void peachA() {
        int peachs = 1;
        for (int i = 9; i >= 1; i--) {
            peachs = 2 * (peachs + 1);
            System.out.println("第" + i + "天有" + peachs + "个桃子");
        }
    }
}

6.电影院第几排?

电影院太黑无法看清,可以问前面,前面的人再问前面,当前面人发现前面没有椅子,可以确定坐在第一排

  • 递:分解问题n->n-1->…->1(出口条件的情况)

  • 归:组合小规模问题的解得到最终问题的解n<-n-1<-…2<-1

  • location(n)=location(n-1)+1

//n代表实际所处的排数
public static int lacation(int n){
    //递归出口
    if(n==1)
        return 1;//第一排的同学直接知道自己在第一排
    return location(n-1)+1
}

总结:

  • 递归的关键在于找到递推公式和递归出口
  • 递归的弊端:产生重复计算,效率低下,大多递归可以用循环方法做出,但循环有时同样不是最好方式

你可能感兴趣的:(学习日志,算法,java,递归法)