生活随笔
收集整理的這篇文章主要介紹了
LeetCode 1293. 网格中的最短路径(DP/BFS)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1. 題目
給你一個 m * n 的網格,其中每個單元格不是 0(空)就是 1(障礙物)。
每一步,您都可以在空白單元格中上、下、左、右移動。
如果您 最多 可以消除 k 個障礙物,請找出從左上角 (0, 0) 到右下角 (m-1, n-1) 的最短路徑,并返回通過該路徑所需的步數。
如果找不到這樣的路徑,則返回 -1。
示例
1:
輸入:
grid
=
[[0,0,0],[1,1,0],[0,0,0],[0,1,1],[0,0,0]],
k
= 1
輸出:
6
解釋:
不消除任何障礙的最短路徑是
10。
消除位置
(3,2) 處的障礙后,最短路徑是
6 。
該路徑是
(0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (3,2) -> (4,2).示例
2:
輸入:
grid
=
[[0,1,1],[1,1,1],[1,0,0]],
k
= 1
輸出:
-1
解釋:
我們至少需要消除兩個障礙才能找到這樣的路徑。提示:
grid
.length
== m
grid
[0].length
== n
1 <= m
, n
<= 40
1 <= k
<= m
*n
grid
[i
][j
] == 0 or 1
grid
[0][0] == grid
[m
-1][n
-1] == 0
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/shortest-path-in-a-grid-with-obstacles-elimination
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
2. 解題
- dp[i][j][s] 表示到(i,j)位置,消除了s個障礙物的最短步數
- 先用 BFS搜索跟起點相連的 非障礙物(0),記錄每個到達的 0 位置 dp[i][j][0]的步數(BFS的層數)
- 然后在遍歷所有可能的s,遍歷所有的位置 i,j,下一個位置狀態 ni,nj
- 如果(grid[ni][nj] && s+1 <= k) 是障礙物, 且還可以搬走
則 dp[ni][nj][s+1] = min(dp[ni][nj][s+1], dp[i][j][s]+1) - 如果 grid[ni][nj]不是障礙物
則 dp[ni][nj][s] = min(dp[ni][nj][s], dp[i][j][s]+1)
class Solution {
public:int shortestPath(vector
<vector
<int>>& grid
, int k
) {vector
<vector
<int>> dir
= {{1,0},{0,1},{0,-1},{-1,0}};int m
= grid
.size(), n
= grid
[0].size(), i
, j
, ni
, nj
, s
= 0, d
;vector
<vector
<vector
<int>>> dp(m
,vector
<vector
<int>>(n
, vector
<int>(k
+1, INT_MAX
)));dp
[0][0][0] = 0;vector
<vector
<bool>> vis(m
, vector
<bool>(n
,false));queue
<vector
<int>> q
;q
.push({0,0});vis
[0][0] = true;while (!q
.empty()) {int size
= q
.size();while(size
--){i
= q
.front()[0];j
= q
.front()[1];q
.pop();dp
[i
][j
][0] = s
;for(d
= 0; d
< 4; ++d
){ni
= i
+dir
[d
][0];nj
= j
+dir
[d
][1];if(ni
<0 || ni
>= m
|| nj
<0 || nj
>= n
|| vis
[ni
][nj
] || grid
[ni
][nj
])continue;q
.push({ni
,nj
});vis
[ni
][nj
] = true;}}s
++;}for(s
= 0; s
<= k
; s
++){ for(i
= 0; i
< m
; i
++) { for(j
= 0; j
< n
; j
++){ if(dp
[i
][j
][s
] == INT_MAX
)continue;for(d
= 0; d
< 4; ++d
){ ni
= i
+dir
[d
][0];nj
= j
+dir
[d
][1];if(ni
<0 || ni
>= m
|| nj
<0 || nj
>= n
)continue;if(grid
[ni
][nj
] && s
+1 <= k
)dp
[ni
][nj
][s
+1] = min(dp
[ni
][nj
][s
+1], dp
[i
][j
][s
]+1);else if(!grid
[ni
][nj
])dp
[ni
][nj
][s
] = min(dp
[ni
][nj
][s
], dp
[i
][j
][s
]+1);}}}}int minstep
= INT_MAX
;for(s
= 0; s
<= k
; ++s
)minstep
= min(minstep
, dp
[m
-1][n
-1][s
]);return minstep
==INT_MAX
? -1 : minstep
;}
};
640 ms 25.2 MB
- 或者直接BFS,隊列內存儲<i, j, 搬運障礙物次數>
class Solution {
public:int shortestPath(vector
<vector
<int>>& grid
, int k
) {vector
<vector
<int>> dir
= {{1,0},{0,1},{0,-1},{-1,0}};int m
= grid
.size(), n
= grid
[0].size(), i
, j
, ni
, nj
, step
= 0, curs
, d
;vector
<vector
<vector
<bool>>> vis(m
,vector
<vector
<bool>>(n
, vector
<bool>(k
+1, false)));queue
<vector
<int>> q
;q
.push({0,0,0});vis
[0][0][0] = true;while (!q
.empty()) {int size
= q
.size();while(size
--){i
= q
.front()[0];j
= q
.front()[1];curs
= q
.front()[2];if(i
==m
-1 && j
==n
-1)return step
;q
.pop();for(d
= 0; d
< 4; ++d
){ni
= i
+dir
[d
][0];nj
= j
+dir
[d
][1];if(ni
<0 || ni
>= m
|| nj
<0 || nj
>= n
)continue;if(grid
[ni
][nj
] && curs
+1 <= k
&& !vis
[ni
][nj
][curs
+1]){vis
[ni
][nj
][curs
+1] = true;q
.push({ni
,nj
,curs
+1});}else if(!grid
[ni
][nj
] && !vis
[ni
][nj
][curs
]){vis
[ni
][nj
][curs
] = true;q
.push({ni
,nj
,curs
});}}}step
++;}return -1;}
};
400 ms 41.1 MB
python3 解答
class Solution:def shortestPath(self
, grid
: List
[List
[int]], k
: int) -> int:import queue
dir = [[1,0],[0,1],[0,-1],[-1,0]]m
, n
= len(grid
), len(grid
[0])step
= 0vis
= [[[False]*(k
+1) for _
in range(n
)] for _
in range(m
)]q
= queue
.Queue
(m
*n
*(k
+1))q
.put
([0,0,0])vis
[0][0][0] = Truewhile not q
.empty
():size
= q
.qsize
()while size
> 0:qt
= q
.get
()i
= qt
[0]j
= qt
[1]curs
= qt
[2]if i
==m
-1 and j
==n
-1:return step
for d
in range(4):ni
= i
+dir[d
][0]nj
= j
+dir[d
][1]if ni
<0 or ni
>=m
or nj
<0 or nj
>=n
:continueif grid
[ni
][nj
] and curs
+1 <= k
and not vis
[ni
][nj
][curs
+1]:vis
[ni
][nj
][curs
+1] = Trueq
.put
([ni
,nj
,curs
+1])elif not grid
[ni
][nj
] and not vis
[ni
][nj
][curs
]:vis
[ni
][nj
][curs
] = Trueq
.put
([ni
,nj
,curs
])size
-= 1step
+= 1return -1
2200 ms 18.5 MB
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的LeetCode 1293. 网格中的最短路径(DP/BFS)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。