本文主要是介绍LC 70.爬楼梯,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
70.爬楼梯
假设你正在爬楼梯。需要 n
阶你才能到达楼顶。
每次你可以爬 1
或 2
个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入: n = 2
输出: 2
解释: 有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶
示例 2:
输入: n = 3
输出: 3
解释: 有三种方法可以爬到楼顶。
- 1 阶 + 1 阶 + 1 阶
- 1 阶 + 2 阶
- 2 阶 + 1 阶
提示:
- 1 ≤ n ≤ 45 1 \leq n \leq 45 1≤n≤45
解法一(动态规划)
思路分析:
- 对于多个子问题,采用动态规划算法;按照动规五部曲进行求解;
- 确定dp数组以及下标含义,即
dp[i]
表示第i个台阶,有多少种方法可以爬到 - 然后推导递推公式;因为一次可以爬1或2个台阶,即若要到达第i个台阶,可以由第i-1个台阶爬1个台阶到达,也可以由第i-2个台阶爬2个台阶到达,即到达第i个台阶的方法为,到达第i-1个台阶的方法和到第i-2个台阶方法的总和,即状态转移方程为:
dp[i] = dp[i-1] + dp[i-2]
- 然后确定dp数组的初始化,可以简单得出;对于到第一阶台阶,由一种方法,对于到第二阶方法,有两种方法,即
dp[1] = 1; dp[2] = 2
- 然后确定遍历顺序,即从
i=3
开始遍历到i=n
;因为状态转移方程需要先得到状态dp[i-1]
和dp[i-2]
,否则无法得到正确的当前状态dp[i]
- 打印dp数组,确定是否符合思路与题意
实现代码如下:
class Solution {public int climbStairs(int n) {if (n == 1 || n == 2)return n;int[] dp = new int[n+1];dp[1] = 1;dp[2] = 2;for (int i = 3; i <= n; ++ i) {dp[i] = dp[i-1] + dp[i-2];}return dp[n];}
}
提交结果如下:
解答成功:
执行耗时:0 ms,击败了100.00% 的Java用户
内存消耗:39.5 MB,击败了5.28% 的Java用户
复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
解法二(状态压缩)
思路分析:
- 由解法一得到的状态转移方程;得知下一个状态由可表达的两个状态得出
- 即可以对状态数组进行压缩,使用变量
ans
来表示下一个需要得到的状态,使用变量a
和b
来表示需要的两个状态
实现代码如下:
class Solution {public int climbStairs(int n) {if (n == 1 || n == 2)return n;int ans = 0;// 初始状态int a = 1, b = 2;for (int i = 3; i <= n; ++ i) {ans = a + b; // 状态转移a = b;b = ans;}return ans;}
}
提交结果如下:
解答成功:
执行耗时:0 ms,击败了100.00% 的Java用户
内存消耗:39.4 MB,击败了47.08% 的Java用户
复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
这篇关于LC 70.爬楼梯的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!