63. 不同路徑 II:
一個(gè)機(jī)器人位于一個(gè) m x n
網(wǎng)格的左上角 (起始點(diǎn)在下圖中標(biāo)記為 “Start” )。
機(jī)器人每次只能向下或者向右移動(dòng)一步。機(jī)器人試圖達(dá)到網(wǎng)格的右下角(在下圖中標(biāo)記為 “Finish”)。
現(xiàn)在考慮網(wǎng)格中有障礙物。那么從左上角到右下角將會(huì)有多少條不同的路徑?
網(wǎng)格中的障礙物和空位置分別用 1
和 0
來(lái)表示。
樣例 1:
輸入:
obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
輸出:
2
解釋:
3x3 網(wǎng)格的正中間有一個(gè)障礙物。
從左上角到右下角一共有 2 條不同的路徑:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
樣例 2:
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-596658.html
輸入:
obstacleGrid = [[0,1],[0,0]]
輸出:
1
提示:
- m == obstacleGrid.length
- n == obstacleGrid[i].length
- 1 <= m, n <= 100
- obstacleGrid[i][j] 為 0 或 1
分析:
- 面對(duì)這道算法題目,二當(dāng)家的再次陷入了沉思。
- 這道題和62. 不同路徑 類似,但是由于有隨機(jī)位置的障礙物,所以就不能直接用數(shù)學(xué)的組合數(shù)方式求解了。
- 那么動(dòng)態(tài)規(guī)劃成了此時(shí)的優(yōu)選。每一個(gè)點(diǎn)的不同路徑數(shù)是到達(dá)上面點(diǎn)的不同路徑數(shù)與到達(dá)左面不同路徑數(shù)的和。我們可以按行從上到下的方式處理(按列從左到右處理也是可以的,但是有些別扭,因?yàn)槎S數(shù)組的第一維是行,第二維是列,習(xí)慣上都是按行處理),這樣會(huì)發(fā)現(xiàn)每行只和上一行的結(jié)果有關(guān)系,所以就不需要
m * n
的額外空間,而只需要m
的空間,即滾動(dòng)數(shù)組的思想。
題解:
rust:
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];
}
}
go:
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();
}
};
python:
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]
java:
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];
}
}
非常感謝你閱讀本文~
歡迎【點(diǎn)贊】【收藏】【評(píng)論】三連走一波~
放棄不難,但堅(jiān)持一定很酷~
希望我們大家都能每天進(jìn)步一點(diǎn)點(diǎn)~
本文由 二當(dāng)家的白帽子:https://le-yi.blog.csdn.net/ 博客原創(chuàng)~文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-596658.html
到了這里,關(guān)于算法leetcode|63. 不同路徑 II(rust重拳出擊)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!