LeetCode 70 Climbing Stairs &&剑指Offer10- II. 青蛙跳台阶问题

文章介绍了爬楼梯问题的两种解决方案,一是使用动态规划的迭代方法,二是利用矩阵快速幂优化斐波那契数列计算,这两种方法都在O(n)时间内解决,其中矩阵快速幂可在O(logn)时间内求解。此外,还提到了结果需对1e9+7取模的处理方式。
摘要由CSDN通过智能技术生成

参考资料:《程序员代码面试指南》

70. Climbing Stairs
You are climbing a staircase. It takes n steps to reach the top.

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

 

Example 1:

Input: n = 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps

思路1:迭代

  public int climbStairs2(int n) {

         // dp[i] = dp[i-1]+dp[i-2]
         // dp[n] is ans
         int[] dp = new int[n+1];
         dp[0]=1;
        dp[1]=1;
        if(n>=2)
        {
            dp[2]=2;
            for(int i=3;i<=n;i++)
            {
                dp[i] = dp[i-1]+dp[i-2];
            }
        }
        
        return dp[n];
     }

思路2:加速矩阵乘法

斐波那契数列的递推公式可以写成矩阵幂乘上递归base case的形式, 从而 把求第n项的问题 转化成了 求矩阵n次幂的问题 (这里具体的问题是求矩阵的n-2次幂),详细推导可以看 《程序员代码面试指南》斐波那契数列篇。
求矩阵n次幂,可以在O(lg n) 的时间内做到,思想是借鉴了 求整数的n次幂的做法, 写出n的二进制形式,只在’1‘位上累乘。详细推导可以看 《程序员代码面试指南》。
宫水三叶姐的矩阵快速幂解法

  public int climbStairs(int n) {
          if(n<1)
          {
              return 0;
          }

          if(n==1||n==2)
          {
              return n;
          }

          int[][] base = {{1,1},{1,0}};
          int[][] res = matrixPower(base,n-2);
          return 2*res[0][0]+res[1][0];
      }
      public int[][] matrixPower(int[][] base, int k)
      {
          int n=base.length;
          int[][] ele = new int[n][n];
          for(int i=0;i<n;i++)
          {
              ele[i][i]=1;
          }
        
          for(;k!=0;k>>=1)
          {
              if((k&1)==1)
              {
                  ele = matrixMtl(base,ele);
              }
              base = matrixMtl(base,base);
          }
          return ele;
      }
      public int[][] matrixMtl(int[][] ma, int[][] mb)
      {
          int[][] res = new int[ma.length][ma[0].length];
          for(int i=0;i<res.length;i++)
          {
              for(int j=0;j<res[0].length;j++)
              {
                  for(int k=0;k<ma[0].length;k++)
                  {
                      res[i][j]+=ma[i][k]*mb[k][j];
                  }
              }
          }
          return res;
      }

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

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

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2
输出:2
示例 2:

输入:n = 7
输出:21
示例 3:

输入:n = 0
输出:1

=================
注意迭代写法,还有题目中要求结果取模,记得取模运算的特性,
对和取模 = 对加项分别取模的和 (可能还要再取模),比如:
10%3 = (7+3)%3 = 7%3 + 3%3 = 1+0=1;
在这里插入图片描述

class Solution {
    public int numWays(int n) {
        int a=1,b=1,sum=0;
        for(int i=0;i<n;i++){
            sum = (a+b)%1000000007;
            a = b;
            b = sum;
        }
        return a;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值