爬楼梯问题-斐波那契序列的应用.md

    1. N 阶楼梯,一次可以爬1、2步,求爬楼梯的种类数 ------ 斐波那契序列
    1. 变形:N 阶楼梯,一次可以爬1、2、3...n步,求爬楼梯的种类数 ------- 2的阶乘

/**
 * 一次爬1\2步,所求结果是斐波那契序列
 *
 */
public class ClimbingStairs {
    // Sol 1: 递归 ,超时
    // 递归 公式:F(n) = F(n - 1) + F(n - 2),n>=2; F(1) = 1, F(0) = 0;
    // Time: O(1.618 ^ n) Space: O(n) 空间复杂度取决于递归的深度
    public int climbStairs1(int n) {
        if (n < 2)
            return 1;
        else
            return climbStairs1(n - 1) + climbStairs1(n - 2);
    }

    // Sol 2: 迭代
    // Time: O(n) Space: O(1)
    public int climbStairs(int n) {
        int prev = 0, curr = 1;
        for (int i = 0; i < n; i++) {
            int tmp = curr;
            curr += prev;
            prev = tmp;
        }
        return curr;
    }

    // Sol 3: 数学公式, 见笔记
    // Time: O(n) Space: O(1)
    public int climbStairs3(int n) {
        final double s = Math.sqrt(5);
        return (int) ((Math.pow((1 + s) / 2, n + 1) - Math.pow((1 - s) / 2, n + 1)) * (1.0 / s));
    }

    /**
     * 变形:如果每次可怕的步数是1\2\3\...\n
     * f(1) = 1
     * f(2) = 2
     * f(3) = 4
     * f(4) = 8
     * f(5) = 32
     * f(6) = 64
     * f(n) = f(n-1) + f(n-2) + ... + f(2) + f(1)
     */
    public int climStainrsN(int n) {
        int result = 1;
        for (int i = 1; i < n; i++) {
            result = result * 2;
        }
        return result;
    }

    public static void main(String[] args) {
        ClimbingStairs sol = new ClimbingStairs();
        for (int i = 1; i <= 6; i++) {
            System.out.println("n = " + i + ", step =" + sol.climStainrsN(i));
        }
    }


}


posted on 2017-04-12 19:53  BYRHuangQiang  阅读(308)  评论(0编辑  收藏  举报

导航