63. さまざまなパス II:
ロボットはm x n
グリッドの左上隅に配置されます (下の図では開始点に「開始」というラベルが付けられています)。
ロボットは一度に 1 ステップ下または右へのみ移動できます。ロボットはグリッドの右下隅 (下の画像で「終了」とマークされている) に到達しようとします。
ここで、グリッド内に障害物があると考えてみましょう。では、左上から右下までの異なるパスは何通りあるでしょうか?
グリッド内の障害物と空き位置は、それぞれ1
とで示されます0
。
例 1:
输入:
obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:
2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
例 2:
输入:
obstacleGrid = [[0,1],[0,0]]
输出:
1
ヒント:
- m == 障害物グリッド.長さ
- n == 障害物グリッド[i].length
- 1 <= m、n <= 100
- 障害物グリッド[i][j]は 0 または 1
分析します:
- このアルゴリズムの問題に直面して、二代目リーダーは再び考え込んでしまいました。
- この問題は62. 異なる経路に似ていますが、ランダムな位置に障害物があるため、数学的な組み合わせ数によって直接解くことはできません。
- その場合、現時点では動的プログラミングが第一の選択肢になります。各ポイントへの個別のパスの数は、上の点への個別のパスの数と左側への個別のパスの数の合計です。行ごとに上から下に処理できます (列ごとに左から右に処理することもできますが、2 次元配列の最初の次元が行であり、2 次元が 2 次元であるため、少し厄介です)行を使用するのが通例です (処理)、各行は前の行の結果にのみ関連していることがわかり、余分な
m * n
スペースは必要ありませんが、m
スペースだけが必要です。アレイをローリングします。
答え:
さび:
impl Solution {
pub fn unique_paths_with_obstacles(obstacle_grid: Vec<Vec<i32>>) -> i32 {
let rows = obstacle_grid.len();
let cols = obstacle_grid[0].len();
let mut dp = vec![0; cols];
if obstacle_grid[0][0] == 0 {
dp[0] = 1;
}
(0..rows).for_each(|r| {
(0..cols).for_each(|c| {
if obstacle_grid[r][c] == 1 {
dp[c] = 0;
} else if c > 0 && obstacle_grid[r][c - 1] == 0 {
dp[c] += dp[c - 1];
}
});
});
return dp[cols - 1];
}
}
行く:
func uniquePathsWithObstacles(obstacleGrid [][]int) int {
rows, cols := len(obstacleGrid), len(obstacleGrid[0])
dp := make([]int, cols)
if obstacleGrid[0][0] == 0 {
dp[0] = 1
}
for r := 0; r < rows; r++ {
for c := 0; c < cols; c++ {
if obstacleGrid[r][c] == 1 {
dp[c] = 0
continue
}
if c > 0 && obstacleGrid[r][c-1] == 0 {
dp[c] += dp[c-1]
}
}
}
return dp[cols-1]
}
c++:
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
const int rows = obstacleGrid.size(), cols = obstacleGrid.at(0).size();
vector<int> dp(cols);
dp[0] = (obstacleGrid[0][0] == 0);
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
if (obstacleGrid[r][c] == 1) {
dp[c] = 0;
continue;
}
if (c > 0 && obstacleGrid[r][c - 1] == 0) {
dp[c] += dp[c - 1];
}
}
}
return dp.back();
}
};
パイソン:
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
rows, cols = len(obstacleGrid), len(obstacleGrid[0])
dp = [0] * cols
if obstacleGrid[0][0] == 0:
dp[0] = 1
for r in range(rows):
for c in range(cols):
if obstacleGrid[r][c] == 1:
dp[c] = 0
continue
if c > 0 and obstacleGrid[r][c - 1] == 0:
dp[c] += dp[c - 1]
return dp[cols - 1]
ジャワ:
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
final int rows = obstacleGrid.length, cols = obstacleGrid[0].length;
final int[] dp = new int[cols];
if (obstacleGrid[0][0] == 0) {
dp[0] = 1;
}
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
if (obstacleGrid[i][j] == 1) {
dp[j] = 0;
continue;
}
if (j > 0 && obstacleGrid[i][j - 1] == 0) {
dp[j] += dp[j - 1];
}
}
}
return dp[cols - 1];
}
}
この記事を読んでいただきありがとうございます~
【いいね】【お気に入り】【コメント】へようこそ~三回連続で歩きましょう~
諦めるのは難しいことではありませんが、やり抜くのはカッコいいですね~
みんなで改善できればと思います毎日少しずつ〜この記事は二代目マスターのホワイトハット
が書いています:https://le-yi.blog.csdn.net/ブログオリジナル〜