LeetCode 剑指Offer 10- II 青蛙跳台阶问题

该博客讨论了LeetCode剑指Offer 10- II 青蛙跳台阶问题的解题思路,包括使用动态规划和矩阵快速幂两种方法。动态规划解决方案强调了当n=0时返回值为1,并介绍了动态转移方程。矩阵快速幂方法也被用于解决此问题。
摘要由CSDN通过智能技术生成

剑指Offer 10- II 青蛙跳台阶问题

题目

在这里插入图片描述

解题

注意当 n = 0 时,返回值为 1。
以下题目解题方法相同,区别点是根据题干,动态转移方程会有差异。

题目解题
面试题 08.01. 三步问题三步问题题解
剑指 Offer 10- I. 斐波那契数列斐波那契数列题解
70. 爬楼梯爬楼梯
剑指Offer 10- II 青蛙跳台阶问题青蛙跳台阶问题

解题一:动态规划

// javascript
var numWays = function(n) {
	const vec = [1, 1, 2];
    if (n < 3) return vec[n];
    const MOD = 1e9 + 7;
    let p = 1, q = 2, r;
    for (let i = 3; i <= n; ++i) {
        r = (p + q) % MOD;
        p = q;
        q = r;
    }
    return r;
};

在这里插入图片描述

解题二:矩阵快速幂

[ F ( n − 1 ) F ( n ) ] = [ 0 1 1 1 ] n − 1 ∗ [ F ( 0 ) F ( 1 ) ] \begin{bmatrix} F(n-1) \\ F(n) \end{bmatrix} = {\begin{bmatrix} 0 & 1 \\ 1 & 1\end{bmatrix}}^{n-1} * \begin{bmatrix} F(0) \\ F(1) \end{bmatrix} [F(n1)F(n)]=[0111]n1[F(0)F(1)]

// javascript
var numWays = function(n) {
    const vec = [1, 1];
    if (n < 2) return vec[n];
    const A = [[0, 1], [1, 1]];
    const Amul = matpow(A, n - 1);
    const res = matmul(Amul, [[vec[0], 0], [vec[1], 0]]);
    return res[1][0];
};

const matpow = (a, n) => {
    let ret = [[1, 0], [0, 1]];
    // 以 7 (0b111) 为例,a^7 = a^4 + a^2 + a^1
    while (n > 0) {
        if ((n & 1) === 1) {
            ret = matmul(ret, a);
        }
        n >>= 1;
        a = matmul(a, a);
    }
    return ret;
};

const matmul = (a, b) => {
    const m1 = a.length, n1 = a[0].length;
    const m2 = b.length, n2 = b[0].length;
    if (n1 !== m2) {
        throw new Error('these 2 matrix can not be multiplied!');
    }
    const MOD = BigInt(1e9 + 7);
    // 初始化时要用 BigInt 类型 => 数字后面加 n
    const res = new Array(m1).fill(0n).map(() => new Array(n2).fill(0n));
    for (let i = 0; i < m1; ++i) {
        for (let j = 0; j < n2; ++ j) {
            for (let k = 0; k < n1; ++k) {
                res[i][j] += BigInt(a[i][k]) * BigInt(b[k][j]); 
            }
            // 结果取模
            res[i][j] %= MOD;
        }
    }
    return res;
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值