面试题9:斐波拉契数列及其变种

来源:互联网 发布:php 私有属性 编辑:程序博客网 时间:2024/05/29 02:47

题目一:现在要求输入一个整数n,请你输出斐波那契数列的第n项。


解题思路:

这里写图片描述

  1. 由公式得到递归,效率太低!
  2. 保存中间值,由下往上计算!时间复杂度是O(n)。

代码实现:

public class Test09 {    /**     * 写一个函数,输入n,求斐波那契(Fibonacci) 数列的第n项     * @param n Fibonacci数的项数     * @return 第n项的结果     */    public static long fibonacci(int n) {        // 当输入非正整数的时候返回0        if (n <= 0) {            return 0;        }        // 输入1或者2的时候返回1        if (n == 1 || n == 2) {            return 1;        }        // 记录前两个(第n-2个)的Fibonacci数的值        long prePre = 1;        // 记录前两个(第n-1个)的Fibonacci数的值        long pre = 1;        // 记录前两个(第n个)的Fibonacci数的值        long current = 2;        // 求解第n个的Fibonacci数的值        for (int i = 3; i <= n ; i++) {            // 求第i个的Fibonacci数的值            current = prePre + pre;            // 更新记录的结果,prePre原先记录第i-2个Fibonacci数的值            // 现在记录第i-1个Fibonacci数的值            prePre = pre;            // 更新记录的结果,pre原先记录第i-1个Fibonacci数的值            // 现在记录第i个Fibonacci数的值            pre = current;        }        // 返回所求的结果        return current;    }    public static void main(String[] args) {        System.out.println(fibonacci(0));        System.out.println(fibonacci(1));        System.out.println(fibonacci(2));        System.out.println(fibonacci(3));        System.out.println(fibonacci(4));        System.out.println(fibonacci(5));        System.out.println(fibonacci(6));        System.out.println(fibonacci(7));    }}

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

public class Solution {    public int JumpFloor(int target) {        return JumpFloor(target, 1, 2);    }    public int JumpFloor(int target, int p, int q) {        if (target == 1) {            return 1;        }        if (target == 2) {            return q;        }        return JumpFloor(target - 1, q, p + q);    }}

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

public class Solution {    //f(n)=f(1)+f(2)+...+f(n-1)    //f(n)=2*f(n-1)    public int JumpFloorII(int target) {        if (target == 0) {            return 1;        }        if (target == 1) {            return 1;        }        int total = 1;        while (target != 1) {            total *= 2;            target--;        }        return total;    }}

题目三:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

抽象问题:画图,举例子!!!发现规律或者隐含的逻辑条件!

public class Solution {    //尾递归    public int RectCover(int target) {        return RectCover(target, 1, 2);    }    private int RectCover(int target, int p, int q) {        if (target < 1) {            return 0;        }        if (target == 1) {            return 1;        }        if (target == 2) {            return q;        }        return RectCover(target - 1, q, p + q);    }}
原创粉丝点击