Given an n x n
binary matrix grid
, return the length of the shortest clear path in the matrix. If there is no clear path, return -1
.
A clear path in a binary matrix is a path from the top-left cell (i.e., (0, 0)
) to the bottom-right cell (i.e., (n - 1, n - 1)
) such that:
- All the visited cells of the path are
0
. - All the adjacent cells of the path are 8-directionally connected (i.e., they are different and they share an edge or a corner).
The length of a clear path is the number of visited cells of this path.
Example 1:
Input: grid = [[0,1],[1,0]]
Output: 2
Example 2:
Input: grid = [[0,0,0],[1,1,0],[1,1,0]]
Output: 4
Example 3:
Input: grid = [[1,0,0],[1,1,0],[1,1,0]]
Output: -1
Constraints:
n == grid.length
n == grid[i].length
1 <= n <= 100
grid[i][j] is 0 or 1
這道題給了一個 nxn
的二維數組,里面都是0和1,讓找出一條從左上角到右下角的干凈路徑,所謂的干凈路徑就是均由0組成,並且定義了相鄰的位置是八個方向,不僅僅是通常的上下左右。例子中還給了圖幫助理解,但是也有一丟丟的誤導,博主最開始以為只需要往右,下,和右下三個方向走就行了,其實並不一定,任何方向都是可能的,說白了還是一道迷宮遍歷的問題。既然是迷宮遍歷求最少步數,那么廣度優先遍歷 Breadth-First Search 就是不二之選了,還是使用一個隊列 queue 來做,初識時將 (0, 0) 放進去,再用一個 TreeSet 來標記訪問過的位置。注意這里的方向數組要用到八個方向,while 循環中用的還是經典的層序遍歷的寫法,就是經典的寫法,沒有啥特殊的地方,博主感覺已經寫了無數次了,在進行這一切之前,先判斷一下起始點,若為1,直接返回 -1 即可,參見代碼如下:
class Solution {
public:
int shortestPathBinaryMatrix(vector<vector<int>>& grid) {
if (grid[0][0] == 1) return -1;
int res = 0, n = grid.size();
set<vector<int>> visited;
visited.insert({0, 0});
queue<vector<int>> q;
q.push({0, 0});
vector<vector<int>> dirs{{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
while (!q.empty()) {
++res;
for (int i = q.size(); i > 0; --i) {
auto t = q.front(); q.pop();
if (t[0] == n - 1 && t[1] == n - 1) return res;
for (auto dir : dirs) {
int x = t[0] + dir[0], y = t[1] + dir[1];
if (x < 0 || x >= n || y < 0 || y >= n || grid[x][y] == 1 || visited.count({x, y})) continue;
visited.insert({x, y});
q.push({x, y});
}
}
}
return -1;
}
};
討論:其實上面的寫法基本上屬於壓線過的 OJ,因為 BFS 基本上屬於遍歷了所有情況的,當數組中有大量的0的時候,這種方法就顯得不是很高效了。論壇上的高分解法,參見大神 lxnn 的帖子,使用到了 A*
搜索,是一種啟發式搜索,有興趣的童鞋可以去研究一下。不過在面試中,一般來說不會考這么難的,基本的 BFS 解法是一定要掌握的。
Github 同步地址:
https://github.com/grandyang/leetcode/issues/1091
參考資料:
https://leetcode.com/problems/shortest-path-in-binary-matrix/
https://leetcode.com/problems/shortest-path-in-binary-matrix/discuss/312706/JAVA-BFS
https://leetcode.com/problems/shortest-path-in-binary-matrix/discuss/313347/A*-search-in-Python