You are given an m x n
integer array grid where grid[i][j]
could be:
Return the number of 4-directional walks from the starting square to the ending square, that walk over every non-obstacle square exactly once.
Input: grid = [[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)
Input: grid = [[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)
Input: grid = [[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.
我们有一个 m x n
的二维数组 grid
,其中每个单元格的值代表不同的含义:
要求从起点出发,经过所有非障碍物的单元格(即所有值为 0 的单元格)恰好一次,最终到达终点。需要计算所有满足条件的路径数量。
grid
中值为 1 和 2 的单元格,分别作为起点和终点。grid
中值为 0 的单元格数量,记为 empty
。empty
个空单元格,并最终到达终点。(start_x, start_y)
和终点 (end_x, end_y)
。empty
的数量。result
用于记录满足条件的路径数量。(x, y)
,已覆盖的空单元格数量 count
。count == empty
,则 result
加一。visited
来记录哪些单元格已经被访问过。class Solution {
public:
int uniquePathsIII(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
int start_x = -1, start_y = -1, end_x = -1, end_y = -1;
int empty = 0;
int result = 0;
// 找到起点、终点,并计算空单元格数量
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
start_x = i;
start_y = j;
} else if (grid[i][j] == 2) {
end_x = i;
end_y = j;
} else if (grid[i][j] == 0) {
empty++;
}
}
}
// 初始化访问数组
vector<vector<bool>> visited(m, vector<bool>(n, false));
// DFS 函数
function<void(int, int, int)> dfs = [&](int x, int y, int count) {
// 如果到达终点且覆盖了所有空单元格
if (x == end_x && y == end_y) {
if (count == empty) {
result++;
}
return;
}
// 标记当前单元格为已访问
visited[x][y] = true;
// 遍历四个方向
int directions[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for (auto& dir : directions) {
int nx = x + dir[0];
int ny = y + dir[1];
if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visited[nx][ny] && grid[nx][ny] != -1) {
dfs(nx, ny, count + (grid[nx][ny] == 0 ? 1 : 0));
}
}
// 回溯
visited[x][y] = false;
};
// 从起点开始 DFS
dfs(start_x, start_y, 0);
return result;
}
};
m
和 n
分别是网格的行数和列数。通过深度优先搜索和回溯的方法,我们可以有效地解决这个问题。关键在于正确地标记已访问的单元格,并在递归过程中确保覆盖所有必要的空单元格。