mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2026-02-02 18:39:09 +08:00
Update
This commit is contained in:
@@ -4,30 +4,34 @@
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
# 70. 爬楼梯
|
||||
# 70. 爬楼梯(进阶版)
|
||||
|
||||
[力扣题目链接](https://leetcode.cn/problems/climbing-stairs/)
|
||||
[卡码网:57. 爬楼梯](https://kamacoder.com/problempage.php?pid=1067)
|
||||
|
||||
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
|
||||
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
|
||||
|
||||
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
|
||||
每次你可以爬至多m (1 <= m < n)个台阶。你有多少种不同的方法可以爬到楼顶呢?
|
||||
|
||||
注意:给定 n 是一个正整数。
|
||||
注意:给定 n 是一个正整数。
|
||||
|
||||
示例 1:
|
||||
输入: 2
|
||||
输出: 2
|
||||
解释: 有两种方法可以爬到楼顶。
|
||||
1. 1 阶 + 1 阶
|
||||
2. 2 阶
|
||||
输入描述:输入共一行,包含两个正整数,分别表示n, m
|
||||
|
||||
输出描述:输出一个整数,表示爬到楼顶的方法数。
|
||||
|
||||
输入示例:3 2
|
||||
|
||||
输出示例:3
|
||||
|
||||
提示:
|
||||
|
||||
当 m = 2,n = 3 时,n = 3 这表示一共有三个台阶,m = 2 代表你每次可以爬一个台阶或者两个台阶。
|
||||
|
||||
此时你有三种方法可以爬到楼顶。
|
||||
|
||||
* 1 阶 + 1 阶 + 1 阶段
|
||||
* 1 阶 + 2 阶
|
||||
* 2 阶 + 1 阶
|
||||
|
||||
示例 2:
|
||||
输入: 3
|
||||
输出: 3
|
||||
解释: 有三种方法可以爬到楼顶。
|
||||
1. 1 阶 + 1 阶 + 1 阶
|
||||
2. 1 阶 + 2 阶
|
||||
3. 2 阶 + 1 阶
|
||||
|
||||
## 思路
|
||||
|
||||
@@ -35,11 +39,13 @@
|
||||
|
||||
**这次终于讲到了背包问题,我选择带录友们再爬一次楼梯!**
|
||||
|
||||
这道题目 我们在[动态规划:爬楼梯](https://programmercarl.com/0070.爬楼梯.html) 中已经讲过一次了,原题其实是一道简单动规的题目。
|
||||
这道题目 我们在[动态规划:爬楼梯](https://programmercarl.com/0070.爬楼梯.html) 中已经讲过一次了,这次我又给本题加点料,力扣上没有原题,所以可以在卡码网[57. 爬楼梯](https://kamacoder.com/problempage.php?pid=1067)上来刷这道题目。
|
||||
|
||||
既然这么简单为什么还要讲呢,其实本题稍加改动就是一道面试好题。
|
||||
我们之前做的 爬楼梯 是只能至多爬两个台阶。
|
||||
|
||||
**改为:一步一个台阶,两个台阶,三个台阶,.......,直到 m个台阶。问有多少种不同的方法可以爬到楼顶呢?**
|
||||
这次**改为:一步一个台阶,两个台阶,三个台阶,.......,直到 m个台阶。问有多少种不同的方法可以爬到楼顶呢?**
|
||||
|
||||
这又有难度了,这其实是一个完全背包问题。
|
||||
|
||||
1阶,2阶,.... m阶就是物品,楼顶就是背包。
|
||||
|
||||
@@ -86,27 +92,31 @@
|
||||
|
||||
以上分析完毕,C++代码如下:
|
||||
```CPP
|
||||
class Solution {
|
||||
public:
|
||||
int climbStairs(int n) {
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
int main() {
|
||||
int n, m;
|
||||
while (cin >> n >> m) {
|
||||
vector<int> dp(n + 1, 0);
|
||||
dp[0] = 1;
|
||||
for (int i = 1; i <= n; i++) { // 遍历背包
|
||||
for (int j = 1; j <= m; j++) { // 遍历物品
|
||||
for (int i = 1; i <= n; i++) { // 遍历物品
|
||||
for (int j = 1; j <= m; j++) { // 遍历背包
|
||||
if (i - j >= 0) dp[i] += dp[i - j];
|
||||
}
|
||||
}
|
||||
return dp[n];
|
||||
cout << dp[n] << endl;
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
* 时间复杂度: O(nm)
|
||||
* 时间复杂度: O(n * m)
|
||||
* 空间复杂度: O(n)
|
||||
|
||||
代码中m表示最多可以爬m个台阶,代码中把m改成2就是 力扣:70.爬楼梯的解题思路。
|
||||
|
||||
**当然注意 力扣是 核心代码模式,卡码网是ACM模式**
|
||||
|
||||
代码中m表示最多可以爬m个台阶,代码中把m改成2就是本题70.爬楼梯可以AC的代码了。
|
||||
|
||||
## 总结
|
||||
|
||||
@@ -129,123 +139,22 @@ public:
|
||||
|
||||
### Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int climbStairs(int n) {
|
||||
int[] dp = new int[n + 1];
|
||||
int m = 2; //有兩個物品:itme1重量爲一,item2重量爲二
|
||||
dp[0] = 1;
|
||||
|
||||
for (int i = 1; i <= n; i++) { // 遍历背包
|
||||
for (int j = 1; j <= m; j++) { //遍历物品
|
||||
if (i >= j) //當前的背包容量 大於 物品重量的時候,我們才需要記錄當前的這個裝得方法(方法數+)
|
||||
dp[i] += dp[i - j];
|
||||
}
|
||||
}
|
||||
|
||||
return dp[n];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Python3:
|
||||
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def climbStairs(self, n: int) -> int:
|
||||
dp = [0]*(n + 1)
|
||||
dp[0] = 1
|
||||
m = 2
|
||||
# 遍历背包
|
||||
for j in range(n + 1):
|
||||
# 遍历物品
|
||||
for step in range(1, m + 1):
|
||||
if j >= step:
|
||||
dp[j] += dp[j - step]
|
||||
return dp[n]
|
||||
```
|
||||
|
||||
### Go:
|
||||
|
||||
```go
|
||||
func climbStairs(n int) int {
|
||||
//定义
|
||||
dp := make([]int, n+1)
|
||||
//初始化
|
||||
dp[0] = 1
|
||||
// 本题物品只有两个1,2
|
||||
m := 2
|
||||
// 遍历顺序
|
||||
for j := 1; j <= n; j++ { //先遍历背包
|
||||
for i := 1; i <= m; i++ { //再遍历物品
|
||||
if j >= i {
|
||||
dp[j] += dp[j-i]
|
||||
}
|
||||
//fmt.Println(dp)
|
||||
}
|
||||
}
|
||||
return dp[n]
|
||||
}
|
||||
```
|
||||
|
||||
### JavaScript:
|
||||
|
||||
```javascript
|
||||
var climbStairs = function(n) {
|
||||
const dp = new Array(n + 1).fill(0);
|
||||
const m = 2;
|
||||
dp[0] = 1;
|
||||
for(let i = 1; i <= n; i++){
|
||||
for(let j = 1; j <= m; j++){
|
||||
if(i >= j) {
|
||||
dp[i] += dp[i - j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[n];
|
||||
};
|
||||
```
|
||||
|
||||
### TypeScript:
|
||||
|
||||
```typescript
|
||||
function climbStairs(n: number): number {
|
||||
const m: number = 2; // 本题m为2
|
||||
const dp: number[] = new Array(n + 1).fill(0);
|
||||
dp[0] = 1;
|
||||
// 遍历背包
|
||||
for (let i = 1; i <= n; i++) {
|
||||
// 遍历物品
|
||||
for (let j = 1; j <= m; j++) {
|
||||
if (j <= i) {
|
||||
dp[i] += dp[i - j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[n];
|
||||
};
|
||||
```
|
||||
|
||||
### Rust:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn climb_stairs(n: i32) -> i32 {
|
||||
let (n, m) = (n as usize, 2);
|
||||
let mut dp = vec![0; n + 1];
|
||||
dp[0] = 1;
|
||||
for i in 1..=n {
|
||||
for j in 1..=m {
|
||||
if i >= j {
|
||||
dp[i] += dp[i - j];
|
||||
}
|
||||
}
|
||||
}
|
||||
dp[n]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
|
||||
Reference in New Issue
Block a user