动态规划(2)
This commit is contained in:
parent
d4a52e012d
commit
36b78d057a
@ -84,7 +84,7 @@ public int uniquePaths(int m, int n) {
|
||||
return 0;
|
||||
}
|
||||
int[][] nums = new int[m+1][n+1];
|
||||
nums[1][1] = 1;
|
||||
nums[1][1] = 1; // 起点方格的走法
|
||||
for(int i=1 ; i<=m ; i++) {
|
||||
for(int j=1 ; j<=n ; j++) {
|
||||
if(i==1 && j==1) {
|
||||
@ -97,4 +97,51 @@ public int uniquePaths(int m, int n) {
|
||||
}
|
||||
```
|
||||
整体思路就是创建一个整数二维数组, m+1和n+1是为了留出第一行和第一列数值都是0
|
||||
方便进行计算, 当然这个也不是必须的, 在循环当中判断也可以, 但是不影响时间和空间复杂度
|
||||
方便进行计算, 当然这个也不是必须的, 在循环当中判断也可以, 但是不影响时间和空间复杂度
|
||||
时间复杂度`O(mn)`
|
||||
空间复杂度`O(mn)`
|
||||
|
||||
#### 进阶
|
||||
如果某些方格存在障碍物, 机器人不能经过这些格子
|
||||
有多少走法该如何计算
|
||||
传入的参数是一个整数二维数组, 其中0代表该位置无障碍, 1代表该位置有障碍
|
||||
|
||||
这个问题同样可以沿用上一题的解法
|
||||
需要补充的就是在障碍物的位置, 右侧和下方的格子
|
||||
其对应的来自左侧和上面的走法应该是0, 因为无法从障碍物走过来
|
||||
|
||||
代码实现
|
||||
```java
|
||||
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
|
||||
int m = obstacleGrid.length;
|
||||
if(m == 0) {
|
||||
return 0;
|
||||
}
|
||||
int n = obstacleGrid[0].length;
|
||||
// 需要排除宽度是0以及高度是0的情况, 这种情况下走法是0
|
||||
// 还需要排除起点位置有障碍和终点位置有障碍的情况, 这种情况下走法也是0
|
||||
if(n == 0 || obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1) {
|
||||
return 0;
|
||||
}
|
||||
int[][] nums = new int[m+1][n+1];
|
||||
nums[1][1] = 1;
|
||||
for(int i=1 ; i<=m ; i++) {
|
||||
for(int j=1 ; j<=n ; j++) {
|
||||
if(i == 1 && j == 1) {
|
||||
continue;
|
||||
}
|
||||
// 判断左侧是否有障碍
|
||||
int left = (i > 1 && obstacleGrid[i-2][j-1] == 0) ? nums[i-1][j] : 0;
|
||||
// 判断上方是否有障碍
|
||||
int top = (j > 1 && obstacleGrid[i-1][j-2] == 0) ? nums[i][j-1] : 0;
|
||||
nums[i][j] = left + top;
|
||||
}
|
||||
}
|
||||
return nums[m][n];
|
||||
}
|
||||
```
|
||||
|
||||
### 总结
|
||||
动态规划的主要应用于使用穷举去解决时间复杂度过高的问题
|
||||
将大问题化解为小问题, 并且记住前面小问题的求解结果, 避免在穷举过程中对前面小问题的重复求解
|
||||
从而降低时间复杂度
|
||||
94
source/_posts/算法/动态规划(2).md
Normal file
94
source/_posts/算法/动态规划(2).md
Normal file
@ -0,0 +1,94 @@
|
||||
---
|
||||
title: 动态规划(2)
|
||||
date: 2018-9-1 21:40:02
|
||||
tags:
|
||||
- 算法
|
||||
- 动态规划
|
||||
categories:
|
||||
- 算法
|
||||
---
|
||||
### 最小路径和
|
||||
|
||||
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
|
||||
说明:每次只能向下或者向右移动一步。
|
||||
<!-- more -->
|
||||
> 示例:
|
||||
输入:
|
||||
[
|
||||
[1,3,1],
|
||||
[1,5,1],
|
||||
[4,2,1]
|
||||
]
|
||||
输出: 7
|
||||
解释: 因为路径 1→3→1→1→1 的总和最小。
|
||||
|
||||
这个问题其实和上一篇当中的 **最大子序和** 可以采用相似的方式来解决
|
||||
创建一个 m x n 的二维数组
|
||||
数组中每个位置记录到达该位置的最小路径和
|
||||
到达该位置的最小路径和 = min(到达左侧位置的最小路径和, 到达上方位置的最小路径和) + 给定数组在当前格的值
|
||||
同时排除掉第一行和第一列的特殊情况
|
||||
|
||||
#### 代码实现
|
||||
```java
|
||||
public int minPathSum(int[][] grid) {
|
||||
int m = grid.length;
|
||||
if(m == 0) {
|
||||
return 0;
|
||||
}
|
||||
int n = grid[0].length;
|
||||
if(n == 0) {
|
||||
return 0;
|
||||
}
|
||||
int[][] nums = new int[m][n];
|
||||
nums[0][0] = grid[0][0];
|
||||
int currentMin = 0;
|
||||
for(int i=0 ; i<m ; i++) {
|
||||
for(int j=0 ; j<n ; j++) {
|
||||
if(i == 0 && j == 0) {
|
||||
continue;
|
||||
}
|
||||
if(i-1 < 0) {
|
||||
currentMin = nums[i][j-1];
|
||||
} else if (j-1 < 0) {
|
||||
currentMin = nums[i-1][j];
|
||||
} else {
|
||||
currentMin = Math.min(nums[i][j-1], nums[i-1][j]);
|
||||
}
|
||||
nums[i][j] = grid[i][j] + currentMin;
|
||||
}
|
||||
}
|
||||
return nums[m-1][n-1];
|
||||
}
|
||||
```
|
||||
时间复杂度是O(mn), 空间复杂度是O(mn)
|
||||
当然空间复杂度可以继续优化, 完全可以在传入的数组上面直接对数值进行覆盖, 不去开辟额外的空间
|
||||
让空间复杂度达到O(1)
|
||||
```java
|
||||
public int minPathSum(int[][] grid) {
|
||||
int m = grid.length;
|
||||
if(m == 0) {
|
||||
return 0;
|
||||
}
|
||||
int n = grid[0].length;
|
||||
if(n == 0) {
|
||||
return 0;
|
||||
}
|
||||
int currentMin = 0;
|
||||
for(int i=0 ; i<m ; i++) {
|
||||
for(int j=0 ; j<n ; j++) {
|
||||
if(i == 0 && j == 0) {
|
||||
continue;
|
||||
}
|
||||
if(i-1 < 0) {
|
||||
currentMin = grid[i][j-1];
|
||||
} else if (j-1 < 0) {
|
||||
currentMin = grid[i-1][j];
|
||||
} else {
|
||||
currentMin = Math.min(grid[i][j-1], grid[i-1][j]);
|
||||
}
|
||||
grid[i][j] = grid[i][j] + currentMin;
|
||||
}
|
||||
}
|
||||
return grid[m-1][n-1];
|
||||
}
|
||||
```
|
||||
Loading…
x
Reference in New Issue
Block a user