题目描述
给定一个只含非负整数的 m x n 网格,找到一条从左上角到右下角的可以使数字之和最小的路径。
注意: 每次只能向下或者向右移动一步。
示例 1:
[[1,3,1],
[1,5,1],
[4,2,1]]
根据上面的数组,返回 7
. 因为路径 1→3→1→1→1 总和最小。
我的解法——DP(AC)
- 每个格子可能从上面、左面走下来。
- 注意:初始边界情况
- 复杂度O(n2)
- 结果:Beat47.37%
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid):
"""
:type obstacleGrid: List[List[int]]
:rtype: int
"""
m = len(obstacleGrid)
n = len(obstacleGrid[0]) if(len(obstacleGrid) != 0) else 0
dp = [[0 for j in range(n)] for i in range(m)] # 注意:初始要设置为0,不是-1了
if(obstacleGrid[0][0] == 0):
dp[0][0] = 1
for i in range(m):
for j in range(n):
if(obstacleGrid[i][j] == 0):
dp[i][j] += dp[i - 1][j] if(i - 1 >= 0 and obstacleGrid[i - 1][j] == 0) else 0
dp[i][j] += dp[i][j - 1] if(j - 1 >= 0 and obstacleGrid[i][j - 1] == 0) else 0
return dp[m - 1][n - 1]
最优解法——改进DP
- 利用grid数组,空间轮转
- sum[j] = min(sum[j],sum[j-1]) + grid[i]/[j]
- 空间复杂度为0
public class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;// row
int n = grid[0].length; // column
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i == 0 && j != 0) {
grid[i][j] = grid[i][j] + grid[i][j - 1];
} else if (i != 0 && j == 0) {
grid[i][j] = grid[i][j] + grid[i - 1][j];
} else if (i == 0 && j == 0) {
grid[i][j] = grid[i][j];
} else {
grid[i][j] = Math.min(grid[i][j - 1], grid[i - 1][j])
+ grid[i][j];
}
}
}
return grid[m - 1][n - 1];
}
}