算法导论 31-3 关于斐波那契数的三个算法

31-3(关于斐波那契数的三个算法) 在已知n的情况下,本题对计算第n个斐波那契数Fn的三种算法的效率进行了比较。假定两个数的加法,减法和乘法的代价都是O(1),与数的大小无关。

a.证明:基于递归式(3.22)计算Fn的直接递归方法的运行时间为n的幂。

b.试说明如何运用记忆法在O(n)时间内计算Fn.

c.试说明如何仅用整数加法和乘法运算,就可以在O(lgn)的时间内计算Fn.(提示:考虑2x2矩阵[0,1,1,1]和它的幂。)

3.22: Fibonacci numbers

We define the Fibonacci numbers by the following recurrence:

F(0) = 0, F(1) = 1, F(i) = F(i-1) + F(i-2) for (i>=2).

/* 31-3 Three algorithms for Fibonacci numbers 3.22
3.22: Fibonacci numbers
We define the Fibonacci numbers by the following recurrence:
F(0) = 0, F(1) = 1, F(i) = F(i-1) + F(i-2) for (i>=2).
 */
public class FibonacciNumbers {
  public static void main(String[] args) {
    for(int i=0; i< 20; i++) {
      System.out.println("fibona("+i+")="+fibona1(i));
    }
    for(int i=0; i< 20; i++) {
      System.out.println("fibona("+i+")="+fibonaByMatrixPower(i+1).getFibonaNb());
    }
    for(int i=0; i< 20; i++) {
      System.out.println("fibona("+i+")="+fibona2(i));
    }
  }
  // b. Show how to compute F(n) in O(n) time using memoization O(n) space.
  public static int fibona2(int n) {
    if(n<0) throw new IllegalArgumentException("Fibonacci(n), n>=0");
    if(n == 0 || n == 1) {
      return n;
    }
    int[] result = new int[n+1];
    result[0] = 0;
    result[1] = 1;
    for(int i=2; i<=n; i++) {
      result[i] = result[i-1] + result[i-2];
    }
    return result[n];
  }
  // b. Show how to compute F(n) in O(n) time using O(1) space.
  public static int fibona1(int n) {
    if(n<0) throw new IllegalArgumentException("Fibonacci(n), n>=0");
    if(n==0) return 0;  // f(0) = 0;
    if(n==1) return 1;
    if(n==2) return 1;
    int fn_1 = 1;
    int fn_2 = 1;
    int fn = 0;
    for(int i=3; i<=n; i++) {
      fn = fn_1 + fn_2;
      fn_2 = fn_1;
      fn_1 = fn;
    }
    return fn;
  }
  // c. Show how to compute Fn in O(lgn) time using only integer addition and multiplication.
  // (Hint: Consider the matrix (0,1) and and its powers.) matrix[0][0] if fibona number
  //                            (1,1)
  // f(0)=a.00, f(1)=(a^2).00, f(n)=(a^(n+1)).00
  public static FibonaMatrix fibonaByMatrixPower(int n) {
    if(n<1) throw new IllegalArgumentException("Fibona(n) by matrix power, n>=1");
    if (n == 1) {
      return FibonaMatrix.getFibonaMatrix();
    }
    FibonaMatrix fibHalf = fibonaByMatrixPower(n>>1);
    FibonaMatrix fib = FibonaMatrix.multiply(fibHalf, fibHalf);
    if((n & 1) == 1) {
      fib = FibonaMatrix.multiply(fib, FibonaMatrix.getFibonaMatrix());
    }
    return fib;
  }
  //F(n)为[0,1,1,1]^n+1的[0][0],这个可用数学归纳法证明, f(n)=(a^(n+1)).[0][0], 
  static class FibonaMatrix {
    final private int[][] matrix = new int[2][2];
    private FibonaMatrix() {
      matrix[0][0] = 0;
      matrix[0][1] = 1;
      matrix[1][0] = 1;
      matrix[1][1] = 1;
    }
    public static FibonaMatrix multiply(FibonaMatrix one, FibonaMatrix another) {
      FibonaMatrix ret = getFibonaMatrix();
      ret.matrix[0][0] = one.matrix[0][0] * another.matrix[0][0] + one.matrix[0][1]*another.matrix[1][0];
      ret.matrix[0][1] = one.matrix[0][0] * another.matrix[0][1] + one.matrix[0][1]*another.matrix[1][1];
      ret.matrix[1][0] = one.matrix[1][0] * another.matrix[0][0] + one.matrix[1][1]*another.matrix[1][0];
      ret.matrix[1][1] = one.matrix[1][0] * another.matrix[0][1] + one.matrix[1][1]*another.matrix[1][1];
      return ret;
    }
    public int getFibonaNb() {
      return matrix[0][0];
    }
    public static FibonaMatrix getFibonaMatrix() {
      return new FibonaMatrix();
    }
  }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值