题目链接:https://leetcode-cn.com/problems/unique-paths-iii/
典型题
找路径数或者最长路径用深搜,找最短路径用宽搜
由于要求每个点都要经历过一次,所以用cnt计算出所有无障碍空格数,然后每次深搜时都递减。
求路径数,所以遍历记录数组vis要时刻回溯,即当前状态下标记为true,深搜结束后再标记回false,以便于下一次从不同路径仍能到达该点
代码如下:
class Solution {
public:
int res = 0;
bool vis[21][21];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
bool inmap(int x, int y, int n, int m) {
return x >= 0 && y >= 0 && x < n && y < m;
}
void dfs(int x, int y, vector<vector<int>>& grid, int cnt, int n, int m) {
//printf("x = %d, y = %d, grid[%d][%d] = %d, cnt = %d\n", x, y, x, y, grid[x][y], cnt);
if(grid[x][y] == 2 && cnt == 1) {
res++;
return;
}
//上面判断过成功状态,如果到终止点或者cnt = 0未返回都说明是错误
if(grid[x][y] == 2 || cnt == 1) {
return;
}
vis[x][y] = true;
for(int i = 0; i < 4; i++) {
int xx = x + dx[i], yy = y + dy[i];
if(inmap(xx, yy, n, m) && grid[xx][yy] != -1 && !vis[xx][yy]) {
dfs(xx, yy, grid, cnt - 1, n, m);
}
}
vis[x][y] = false;
}
int uniquePathsIII(vector<vector<int>>& grid) {
int n = grid.size();
if(n == 0) {
return 0;
}
int m = grid[0].size();
int cnt = n * m;
int sx, sy;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(grid[i][j] == 1) {
sx = i;
sy = j;
} else if(grid[i][j] == -1) {
cnt--;
}
}
}
// vis[sx][sy] = true;
dfs(sx, sy, grid, cnt, n, m);
return res;
}
};