climbing-stairs-动态规划,爬楼梯的路径数

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

 

现在说一下大致思路:求出递推公式

f(n)=f(n-1)+f(n-2) ===>f(n)+f(n-1)=2f(n-1)+f(n-2)

[f(n) f(n-1)]=[[1 1][1 0]][f(n-1) f(n-2)]

可以得到递推矩阵

所以该算法的关键点就是:1.需要求出递推矩阵;2.写一个方法,能够实现矩阵相乘

虽然代码量会比其他几个方法大,但是算法复杂度比较低

复制代码
* 动态规划解法
 */
public int climbStairs3(int n) {
    if (n <= 0)
        return 0;
    if (n == 1)
        return 1;
    if (n == 2)
        return 2;
 
    int[][] base = { { 1, 1 }, { 1, 0 } };
    int[][] res = matrixPower(base, n - 2);
 
    return 2*res[0][0] + res[1][0];
}
/*
 * 两个矩阵相乘
 */
private int[][] muliMatrix(int[][] m1, int[][] m2) {
    int[][] res = new int[m1.length][m2[0].length];
    for (int i = 0; i < m1.length; i++) {
        for (int j = 0; j < m2[0].length; j++) {
            for (int k = 0; k < m2.length; k++) {
                res[i][j] += m1[i][k] * m2[k][j];
            }
        }
    }
    return res;
}
复制代码

包含三种最常用的回答,第一最优,第三最差 

复制代码
* 空间复杂度O(1);
 */
public int climbStairs(int n) {
    if (n < 3)
        return n;
    int one_step_before = 2;
    int two_steps_before = 1;
    int all_ways = 0;
    for (int i = 2; i < n; i++) {
        all_ways = one_step_before + two_steps_before;
        two_steps_before = one_step_before;
        one_step_before = all_ways;
    }
    return all_ways;
}
/*
 * 空间复杂度O(n);
 */
public int climbStairs_2(int n) {
    if (n < 3)
        return n;
    int[] res = new int[n + 1];
    res[1] = 1;
    res[2] = 2;
    for (int i = 3; i <= n; i++) {
        res[i] = res[i - 1] + res[i - 2];
    }
    return res[n];
}
/*
 * 方法一:递归 时间复杂度高
 */
public int climbStairs_1(int n) {
    if (n < 1)
        return 0;
    if (n == 1)
        return 1;
    if (n == 2)
        return 2;
    return climbStairs_1(n - 1) + climbStairs_1(n - 2);
}
复制代码

 斐波那契数列

复制代码
class Solution {
public:
    int climbStairs(int n) {
        int f = 1;
        int g = 0;
        while(n--){
            f += g;
            g = f -g;          
        }
        return f;
    }
};
复制代码

 

posted @   鸭子船长  阅读(244)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2017-09-11 make_pair
2017-09-11 fwrite和fread函数的用法小结(转)
2017-09-11 函数fseek() 用法(转)
2015-09-11 表示数值的字符串
点击右上角即可分享
微信分享提示