跳台阶(斐波那契数列)

一、斐波那契数列

题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39
思路:

1、用递归,系统会让一个超大的n来让Stack Overflow,所以递归就不考虑了。使用迭代。
2、考虑负数,极限,算法的时间空间复杂度

     斐波那契数,注意:本题目n1开始,f(0)=0;
        f(n)=   1                    n=1;
                1                    n=2;
                f(n-1)+f(n-2)        n>2;
public class Solution7 {
    public int Fibonacci(int n) {
        if(n<=0) return 0;
        if(n==1||n==2) return 1;
        else{
            return Fibonacci(n-1)+Fibonacci(n-2);
        }
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Solution7 sol = new Solution7();
        System.out.println("输入n:");
        while(scanner.hasNext()){
            int n = scanner.nextInt();
            System.out.println("第"+n+"项为"+sol.Fibonacci(n));
        }
    }
}

二、跳台阶

题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路:

a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);

b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)

c.由a\b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2)

d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2

e.可以发现最终得出的是斐波那契数列的另一种形式;

f. 当前台阶的跳法总数=当前台阶后退一阶的台阶的跳法总数+当前台阶后退二阶的台阶的跳法总数

        注意:本题目f(1)=1,f(2)=2;
        f(n)=   1                    n=1;
                2                    n=2;
                f(n-1)+f(n-2)        n>2;
public class Solution {
     public int JumpFloor(int target) {

         if(target<=0){return -1;}
         if(target==1){return 1;}
         if(target==2){return 2;}

         //第一阶和第二阶考虑过了,初始当前台阶为第三阶,向后迭代

         int s1 =1;
         int s2 =2;
         int s =0;
         for(int i=2;i<target;i++){
             s = s1 + s2;
             s1 = s2;
             s2 = s;
         }
         return s;
     }
     public static void main(String[] args) {
         Solution s = new Solution();
         System.out.println(s.JumpFloor(4));
        }
 }

public class Solution6 {
    public int JumpFloor(int target) {
        if (target <=0 )
            return -1;
        else if (target == 1)
            return 1;
        else if (target == 2)
            return 2;
        else {
            //第一阶和第二阶考虑过了,初始当前台阶为第三阶,向后迭代
            return JumpFloor(target - 1) + JumpFloor(target - 2);
        }

    }

public static void main(String[] args) {

        @SuppressWarnings("resource")
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入台阶数");
        while (scanner.hasNext()) {
            int target = scanner.nextInt();
            Solution6 s = new Solution6();
            System.out.println(s.JumpFloor(target));
        }
    }

}

三、变态跳台阶

题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

思路:

关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:

f(1) = 1

f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。

f(3) = f(3-1) + f(3-2) + f(3-3)

f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-(n-1)) + f(n-n)

说明:

1)这里的f(n) 代表的是n个台阶有一次1,2,…n阶的 跳法数。

2)n = 1时,只有1种跳法,f(1) = 1

3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)

4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,

那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)

因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)

5) n = n时,会有n中跳的方式,1阶、2阶…n阶,得出结论:

f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)

6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:

f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)

f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)

可以得出:

f(n) = 2*f(n-1)

7) 得出最终结论,在n阶台阶,一次有1、2、…n阶的跳的方式时,总得跳法为:


        f(n)=   1                    n=0;
                1                    n=1;
                2*f(n-1)             n>2;

注意:本题目f(1)=1,f(2)=2。f(0)=1需要单独提出,相当于f(n-n)表明可以一次可以跳到顶点。
import java.util.Scanner;
public class Solution {

    public int JumpFloorII(int target) {

        if(target<=0) return 0;
        else if(target==1) return 1;
        else{
            return  2 * JumpFloorII(target - 1);
        }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Solution sol = new Solution();
        System.out.println("输入target:");
        while(scanner.hasNext()){
            int n = scanner.nextInt();
            System.out.println(sol.JumpFloorII(n));
        }
    }


}

或者

public int JumpFloorII(int target) {
     //计算2的次方可以通过移位代替
    return 1<<(target-1);  
    }

猜你喜欢

转载自blog.csdn.net/lulu950817/article/details/79850964