晶片短缺,IHS 調低 Q1 全球汽車產量預期,30% 增幅難實現
阿新 • • 發佈:2021-04-03
一、題目
一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記為“Start” )。
機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為“Finish”)。
現在考慮網格中有障礙物。那麼從左上角到右下角將會有多少條不同的路徑?
網格中的障礙物和空位置分別用 1 和 0 來表示。
二、思路
動態規劃:
跟題目不同路徑
很相似,動態規劃的解法,設定有一陣列dp,dp[i][j]表示可以到達(i, j)格子的路徑數量,可以得到狀態轉移方程:
d
p
[
i
]
[
j
]
=
d
p
[
i
]
[
j
−
1
]
+
d
p
[
i
−
1
]
[
j
]
dp[i][j]=dp[i][j-1]+dp[i-1][j]
dp[i][j]=dp[i][j−1]+dp[i−1][j]而不一樣的是需要考慮到障礙物的情況,有障礙物的網格處於不可達狀態,也就是當obstacleGrid[i][j]==0
時,dp[i][j]=0
.
空間壓縮到一維:
由於狀態(i, j)狀態只依賴於上一行和前一列,所以可以將dp陣列降為二維:
d
p
[
i
]
=
d
p
[
i
]
+
d
p
[
i
−
1
dp[i] = dp[i]+dp[i-1
dp[i]=dp[i]+dp[i−1同樣的,當obstacleGrid[i][j]==0
時,dp[j]=0
.
三、程式碼
動態規劃
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int[][] dp = new int[obstacleGrid.length][obstacleGrid[0].length];
dp[0][0] = obstacleGrid[0][0] == 1? 0 : 1;;
for (int i = 1; i < dp[0].length; i++) { // 初始化第一行
if (obstacleGrid[0][i] == 1) {
dp[0][i] = 0;
} else {
dp[0][i] = dp[0][i-1]; // 如果出現過障礙物,則可達為0
}
}
for (int row = 1; row < dp.length; row++) {
for (int col = 0; col < dp[0].length; col++) {
if (obstacleGrid[row][col] == 1) { // 障礙物處不可達
dp[row][col] = 0;
continue;
}
if (col == 0) {
dp[row][col] = dp[row-1][col]; // 考慮第0列的情況
} else {
dp[row][col] = dp[row-1][col] + dp[row][col-1]; // 狀態轉移
}
}
}
return dp[dp.length - 1][dp[0].length - 1];
}
}
時間複雜度為O(row*col),空間複雜度為O(row*col).
空間壓縮到一維:
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int[] dp = new int[obstacleGrid[0].length];
dp[0] = obstacleGrid[0][0] == 1? 0 : 1;;
for (int i = 1; i < dp.length; i++) {
if (obstacleGrid[0][i] == 1) {
dp[i] = 0;
} else {
dp[i] = dp[i-1];
}
}
for (int row = 1; row < obstacleGrid.length; row++) {
for (int col = 0; col < obstacleGrid[0].length; col++) {
if (obstacleGrid[row][col] == 1) {
dp[col] = 0;
continue;
}
if (col == 0) {
dp[col] = dp[col];
} else {
dp[col] = dp[col] + dp[col-1];
}
}
}
return dp[dp.length - 1];
}
}
時間複雜度為O(row*col),空間複雜度為O(col).