On a 2-dimensional grid
, there are 4 types of squares:
1
represents the starting square. There is exactly one starting square.2
represents the ending square. There is exactly one ending square.0
represents empty squares we can walk over.-1
represents obstacles that we cannot walk over.
Return the number of 4-directional walks from the starting square to the ending square, that walk over every non-obstacle square exactly once.
Example 1:
Input: [[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
Output: 2
Explanation: We have the following two paths:
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)
Example 2:
Input: [[1,0,0,0],[0,0,0,0],[0,0,0,2]]
Output: 4
Explanation: We have the following four paths:
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3)
2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3)
3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3)
4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3)
Example 3:
Input: [[0,1],[2,0]]
Output: 0
Explanation:
There is no path that walks over every empty square exactly once.
Note that the starting and ending square can be anywhere in the grid.
Note:
1 <= grid.length * grid[0].length <= 20
這道題是 Unique Path 系列的第三道,雖說是拓展,但是說實話,博主感覺跟前兩道 Unique Paths II 和 Unique Paths 的差異還是挺大的,那兩道都是要用動態規划來做,而這道卻是更傳統的迷宮遍歷的做法。這里給了一個二維數組 grid,里面有四種狀態,1表示起點,2表示終點,0表示通路,-1 表示障礙物不能通過。現在讓返回從起點到終點,並且經過每個可通過的位置1次的不同路徑的個數。現在來分析,雖說是要從起點到終點,但是每個位置都要經過一次(障礙物除外),就是說即便起點終點挨在一起,還是要整個圖跑一圈再回來才行。不過本質還是遍歷迷宮的問題,一般遍歷迷宮都有廣度優先遍歷 BFS 和深度優先遍歷 DFS 兩種選擇,但是這里 BFS 就不太適用了,因為它是從起點開始一圈一圈往外擴散,直到到達終點位置,適用於求起點到終點的最短路徑的問題。這里可以用 DFS 來做,另外,如果確保當前的路徑正好經過每個位置1次,只經過1次好辦,可以通過修改位置上的狀態,標記已經走過的位置,就不會經過同一個位置兩次。接下來看如何保證經過所有的位置,所有能經過的位置都是0,則把數組中所有的0的個數統計出來,別忘了再加上終點的位置,因為也能到達。這樣每走一步,就把目標步數減1,只要到達終點位置的時候,目標步數正好為0,就說明這條路徑是符合題意的。好了,思路理清了,就來寫代碼吧,先遍歷一遍數組,找出起點位置,和統計出目標步數。然后調用遞歸函數,在遞歸函數中,首先判斷當前位置是否越界,已經當前位置的狀態值是否小於0(訪問過的位置標被記為 -2),是的話就直接返回。否則將當前位置標記為 -2,並且目標值減1,然后對周圍四個位置調用遞歸函數,之后別忘記了恢復狀態,狀態標記0,目標步數加1,參見代碼如下:
class Solution {
public:
int uniquePathsIII(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size(), x0 = 0, y0 = 0, target = 1, res = 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
x0 = i; y0 = j;
} else if (grid[i][j] == 0) {
++target;
}
}
}
helper(grid, target, x0, y0, res);
return res;
}
void helper(vector<vector<int>>& grid, int& target, int i, int j, int& res) {
int m = grid.size(), n = grid[0].size();
if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] < 0) return;
if (grid[i][j] == 2) {
if (target == 0) ++res;
return;
}
grid[i][j] = -2;
--target;
helper(grid, target, i + 1, j, res);
helper(grid, target, i - 1, j, res);
helper(grid, target, i, j + 1, res);
helper(grid, target, i, j - 1, res);
grid[i][j] = 0;
++target;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/980
類似題目:
參考資料:
https://leetcode.com/problems/unique-paths-iii/
https://leetcode.com/problems/unique-paths-iii/discuss/221941/C%2B%2B-brute-force-DFS
https://leetcode.com/problems/unique-paths-iii/discuss/221946/JavaPython-Brute-Force-Backtracking