This commit is contained in:
programmercarl
2022-01-04 10:35:14 +08:00
parent a936850fb7
commit 7e3405938c
5 changed files with 59 additions and 64 deletions

View File

@ -4,7 +4,7 @@
</a> </a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p> <p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
## 62.不同路径 # 62.不同路径
[力扣题目链接](https://leetcode-cn.com/problems/unique-paths/) [力扣题目链接](https://leetcode-cn.com/problems/unique-paths/)
@ -18,26 +18,26 @@
![](https://img-blog.csdnimg.cn/20210110174033215.png) ![](https://img-blog.csdnimg.cn/20210110174033215.png)
输入m = 3, n = 7 * 输入m = 3, n = 7
输出28 * 输出28
示例 2 示例 2
输入m = 2, n = 3 * 输入m = 2, n = 3
输出3 * 输出3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。 解释: 从左上角开始,总共有 3 条路径可以到达右下角。
1. 向右 -> 向右 -> 向下 1. 向右 -> 向右 -> 向下
2. 向右 -> 向下 -> 向右 2. 向右 -> 向下 -> 向右
3. 向下 -> 向右 -> 向右 3. 向下 -> 向右 -> 向右
示例 3 示例 3
输入m = 7, n = 3 * 输入m = 7, n = 3
输出28 * 输出28
示例 4 示例 4
输入m = 3, n = 3 * 输入m = 3, n = 3
输出6 * 输出6
提示: 提示:
* 1 <= m, n <= 100 * 1 <= m, n <= 100
@ -242,7 +242,7 @@ public:
## 其他语言版本 ## 其他语言版本
Java ### Java
```java ```java
/** /**
* 1. 确定dp数组下标含义 dp[i][j] 到每一个坐标可能的路径种类 * 1. 确定dp数组下标含义 dp[i][j] 到每一个坐标可能的路径种类
@ -273,9 +273,9 @@ Java
return dp[m-1][n-1]; return dp[m-1][n-1];
} }
``` ```
Python ### Python
```python ```python
class Solution: # 动态规划 class Solution: # 动态规划
def uniquePaths(self, m: int, n: int) -> int: def uniquePaths(self, m: int, n: int) -> int:
@ -286,7 +286,7 @@ class Solution: # 动态规划
return dp[m - 1][n - 1] return dp[m - 1][n - 1]
``` ```
Go ### Go
```Go ```Go
func uniquePaths(m int, n int) int { func uniquePaths(m int, n int) int {
dp := make([][]int, m) dp := make([][]int, m)
@ -306,7 +306,7 @@ func uniquePaths(m int, n int) int {
} }
``` ```
Javascript ### Javascript
```Javascript ```Javascript
var uniquePaths = function(m, n) { var uniquePaths = function(m, n) {
const dp = Array(m).fill().map(item => Array(n)) const dp = Array(m).fill().map(item => Array(n))

View File

@ -4,7 +4,7 @@
</a> </a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p> <p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
## 70. 爬楼梯 # 70. 爬楼梯
[力扣题目链接](https://leetcode-cn.com/problems/climbing-stairs/) [力扣题目链接](https://leetcode-cn.com/problems/climbing-stairs/)
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
@ -14,19 +14,19 @@
注意:给定 n 是一个正整数。 注意:给定 n 是一个正整数。
示例 1 示例 1
输入: 2 * 输入: 2
输出: 2 * 输出: 2
解释: 有两种方法可以爬到楼顶。 * 解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶 * 1 阶 + 1 阶
2. 2 阶 * 2 阶
示例 2 示例 2
输入: 3 * 输入: 3
输出: 3 * 输出: 3
解释: 有三种方法可以爬到楼顶。 * 解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶 * 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶 * 1 阶 + 2 阶
3. 2 阶 + 1 阶 * 2 阶 + 1 阶
## 思路 ## 思路
@ -200,7 +200,7 @@ public:
关键是 [动态规划:斐波那契数](https://programmercarl.com/0509.斐波那契数.html) 题目描述就已经把动规五部曲里的递归公式和如何初始化都给出来了,剩下几部曲也自然而然的推出来了。 关键是 [动态规划:斐波那契数](https://programmercarl.com/0509.斐波那契数.html) 题目描述就已经把动规五部曲里的递归公式和如何初始化都给出来了,剩下几部曲也自然而然的推出来了。
而本题,就需要逐个分析了,大家现在应该初步感受出[关于动态规划,你该了解这些!](https://leetcode-cn.com/circle/article/tNuNnM/)里给出的动规五部曲了。 而本题,就需要逐个分析了,大家现在应该初步感受出[关于动态规划,你该了解这些!](https://programmercarl.com/动态规划理论基础.html)里给出的动规五部曲了。
简单题是用来掌握方法论的,例如昨天斐波那契的题目够简单了吧,但昨天和今天可以使用一套方法分析出来的,这就是方法论! 简单题是用来掌握方法论的,例如昨天斐波那契的题目够简单了吧,但昨天和今天可以使用一套方法分析出来的,这就是方法论!
@ -212,7 +212,7 @@ public:
## 其他语言版本 ## 其他语言版本
Java ### Java
```Java ```Java
class Solution { class Solution {
public int climbStairs(int n) { public int climbStairs(int n) {
@ -253,7 +253,7 @@ public int climbStairs(int n) {
} }
``` ```
Python ### Python
```python ```python
class Solution: class Solution:
@ -268,7 +268,7 @@ class Solution:
return dp[-1] return dp[-1]
``` ```
Go ### Go
```Go ```Go
func climbStairs(n int) int { func climbStairs(n int) int {
if n==1{ if n==1{
@ -283,7 +283,7 @@ func climbStairs(n int) int {
return dp[n] return dp[n]
} }
``` ```
Javascript: ### Javascript
```Javascript ```Javascript
var climbStairs = function(n) { var climbStairs = function(n) {
// dp[i] 为第 i 阶楼梯有多少种方法爬到楼顶 // dp[i] 为第 i 阶楼梯有多少种方法爬到楼顶

View File

@ -4,7 +4,7 @@
</a> </a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p> <p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
## 509. 斐波那契数 # 509. 斐波那契数
[力扣题目链接](https://leetcode-cn.com/problems/fibonacci-number/) [力扣题目链接](https://leetcode-cn.com/problems/fibonacci-number/)
@ -14,19 +14,19 @@ F(n) = F(n - 1) + F(n - 2),其中 n > 1
给你n ,请计算 F(n) 。 给你n ,请计算 F(n) 。
示例 1 示例 1
输入2 * 输入2
输出1 * 输出1
解释F(2) = F(1) + F(0) = 1 + 0 = 1 * 解释F(2) = F(1) + F(0) = 1 + 0 = 1
示例 2 示例 2
输入3 * 输入3
输出2 * 输出2
解释F(3) = F(2) + F(1) = 1 + 1 = 2 * 解释F(3) = F(2) + F(1) = 1 + 1 = 2
示例 3 示例 3
输入4 * 输入4
输出3 * 输出3
解释F(4) = F(3) + F(2) = 2 + 1 = 3 * 解释F(4) = F(3) + F(2) = 2 + 1 = 3
提示: 提示:
@ -45,7 +45,7 @@ F(n) = F(n - 1) + F(n - 2),其中 n > 1
对于动规,如果没有方法论的话,可能简单题目可以顺手一写就过,难一点就不知道如何下手了。 对于动规,如果没有方法论的话,可能简单题目可以顺手一写就过,难一点就不知道如何下手了。
所以我总结的动规五部曲,是要用来贯穿整个动态规划系列的,就像之前讲过[二叉树系列的递归三部曲](https://programmercarl.com/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.html)[回溯法系列的回溯三部曲](https://programmercarl.com/回溯算法理论基础.html)一样。后面慢慢大家就会体会到,动规五部曲方法的重要性。 所以我总结的动规五部曲,是要用来贯穿整个动态规划系列的,就像之前讲过[二叉树系列的递归三部曲](https://www.programmercarl.com/二叉树的递归遍历.html)[回溯法系列的回溯三部曲](https://programmercarl.com/回溯算法理论基础.html)一样。后面慢慢大家就会体会到,动规五部曲方法的重要性。
### 动态规划 ### 动态规划
@ -151,7 +151,7 @@ public:
这个递归的时间复杂度大家画一下树形图就知道了,如果不清晰的同学,可以看这篇:[通过一道面试题目,讲一讲递归算法的时间复杂度!](https://programmercarl.com/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.html) 这个递归的时间复杂度大家画一下树形图就知道了,如果不清晰的同学,可以看这篇:[通过一道面试题目,讲一讲递归算法的时间复杂度!](https://programmercarl.com/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.html)
# 总结 ## 总结
斐波那契数列这道题目是非常基础的题目,我在后面的动态规划的讲解中将会多次提到斐波那契数列! 斐波那契数列这道题目是非常基础的题目,我在后面的动态规划的讲解中将会多次提到斐波那契数列!
@ -165,10 +165,10 @@ public:
# 其他语言版本 ## 其他语言版本
Java ### Java
```Java ```Java
class Solution { class Solution {
public int fib(int n) { public int fib(int n) {
@ -183,29 +183,24 @@ class Solution {
} }
} }
``` ```
```java ```java
//非压缩状态的版本 //非压缩状态的版本
class Solution { class Solution {
public int fib(int n) { public int fib(int n) {
if (n <= 1) return n; if (n <= 1) return n;
int[] dp = new int[n + 1]; int[] dp = new int[n + 1];
dp[0] = 0; dp[0] = 0;
dp[1] = 1; dp[1] = 1;
for (int index = 2; index <= n; index++){ for (int index = 2; index <= n; index++){
dp[index] = dp[index - 1] + dp[index - 2]; dp[index] = dp[index - 1] + dp[index - 2];
} }
return dp[n]; return dp[n];
} }
} }
``` ```
Python ### Python
```python3 ```python
class Solution: class Solution:
def fib(self, n: int) -> int: def fib(self, n: int) -> int:
if n < 2: if n < 2:
@ -224,7 +219,7 @@ class Solution:
return self.fib(n - 1) + self.fib(n - 2) return self.fib(n - 1) + self.fib(n - 2)
``` ```
Go ### Go
```Go ```Go
func fib(n int) int { func fib(n int) int {
if n < 2 { if n < 2 {
@ -238,7 +233,7 @@ func fib(n int) int {
return c return c
} }
``` ```
Javascript: ### Javascript
```Javascript ```Javascript
var fib = function(n) { var fib = function(n) {
let dp = [0, 1] let dp = [0, 1]

View File

@ -4,7 +4,7 @@
</a> </a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p> <p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
## 746. 使用最小花费爬楼梯 # 746. 使用最小花费爬楼梯
[力扣题目链接](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) [力扣题目链接](https://leetcode-cn.com/problems/min-cost-climbing-stairs/)
@ -181,7 +181,7 @@ public:
这么写看上去比较顺,但是就是感觉和题目描述的不太符。哈哈,也没有必要这么细扣题意了,大家只要知道,题目的意思反正就是要不是第一步不花费,要不是最后一步不花费,都可以。 这么写看上去比较顺,但是就是感觉和题目描述的不太符。哈哈,也没有必要这么细扣题意了,大家只要知道,题目的意思反正就是要不是第一步不花费,要不是最后一步不花费,都可以。
# 总结 ## 总结
大家可以发现这道题目相对于 昨天的[动态规划:爬楼梯](https://programmercarl.com/0070.爬楼梯.html)有难了一点,但整体思路是一样。 大家可以发现这道题目相对于 昨天的[动态规划:爬楼梯](https://programmercarl.com/0070.爬楼梯.html)有难了一点,但整体思路是一样。
@ -200,7 +200,7 @@ public:
## 其他语言版本 ## 其他语言版本
Java ### Java
```Java ```Java
class Solution { class Solution {
public int minCostClimbingStairs(int[] cost) { public int minCostClimbingStairs(int[] cost) {
@ -222,7 +222,7 @@ class Solution {
} }
``` ```
Python ### Python
```python ```python
class Solution: class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int: def minCostClimbingStairs(self, cost: List[int]) -> int:
@ -234,7 +234,7 @@ class Solution:
return min(dp[len(cost) - 1], dp[len(cost) - 2]) return min(dp[len(cost) - 1], dp[len(cost) - 2])
``` ```
Go ### Go
```Go ```Go
func minCostClimbingStairs(cost []int) int { func minCostClimbingStairs(cost []int) int {
dp := make([]int, len(cost)) dp := make([]int, len(cost))
@ -253,7 +253,7 @@ func min(a, b int) int {
} }
``` ```
Javascript ### Javascript
```Javascript ```Javascript
var minCostClimbingStairs = function(cost) { var minCostClimbingStairs = function(cost) {
const dp = [ cost[0], cost[1] ] const dp = [ cost[0], cost[1] ]

View File

@ -16,7 +16,7 @@
所以动态规划中每一个状态一定是由上一个状态推导出来的,**这一点就区分于贪心**,贪心没有状态推导,而是从局部直接选最优的, 所以动态规划中每一个状态一定是由上一个状态推导出来的,**这一点就区分于贪心**,贪心没有状态推导,而是从局部直接选最优的,
在[关于贪心算法,你该了解这些!](https://programmercarl.com/贪心算法理论基础.html)中我举了一个背包问题的例子。 在[关于贪心算法,你该了解这些!](https://mp.weixin.qq.com/s/A9MHJi1a5uugFaqp8QJFWg)中我举了一个背包问题的例子。
例如有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i]得到的价值是value[i] 。**每件物品只能用一次**,求解将哪些物品装入背包里物品价值总和最大。 例如有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i]得到的价值是value[i] 。**每件物品只能用一次**,求解将哪些物品装入背包里物品价值总和最大。