980. Unique Paths III

问题:

给定一个棋盘,

  •  0:可以走的路径
  •  1:起点(有且只有一个)
  •  2:终点(有且只有一个)
  • -1:障碍物,不可走的路径

求从起点到终点,走遍所有可走路径(仅经过一次),的所有路线的可能数。

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

  

解法:Backtracking(回溯算法)

  • 状态:当前走到的格子(i,j),已经走过的步数step
  • 选择:上下左右四个方向(i+1,j)(i,j+1)(i-1,j)(i,j-1)
    • ⚠️  注意:排除以下无效格子:
      • 超出棋盘 i<0 i>=n j<0 j>=m
      • 已经走过:visited[i][j]==true
      • 障碍物:grid[i][j]==-1
    • ⚠️  注意:
      • 在当前格子开始进行下一步之前,记得标记本格子已经走过:visited[i][j]=true
      • 在尝试完四个方向后,递归函数返回之前,擦除走过标记:visited[i][j]=false
  • 退出递归条件:
    • 已经走够步数step==w,同时到达终点格子,则找到一个解:res++,return
    • 已经走够步数step==w,未到达终点,return
    • 未走够步数,到达终点,return

 

代码参考:

 1 class Solution {
 2 public:
 3     int n;
 4     int m;
 5     int w;
 6     int si=0,sj=0, ei=0,ej=0;
 7     bool isValid(vector<vector<int>>& grid, vector<vector<bool>>& visited, int i, int j) {
 8         if(i<n && i>=0 && j<m && j>=0 && grid[i][j]!=-1 && visited[i][j]==false) return true;
 9         else return false;
10     }
11     void dfs(int& res, vector<vector<int>>& grid, vector<vector<bool>>& visited, int i, int j, int step) {
12         if(step==w) {
13             if(i==ei && j==ej) res++;
14             return;
15         }
16         if(i==ei && j==ej) return;
17         
18         visited[i][j] = true;
19         if(isValid(grid, visited, i+1, j)) dfs(res, grid, visited, i+1, j, step+1);
20         if(isValid(grid, visited, i, j+1)) dfs(res, grid, visited, i, j+1, step+1);
21         if(isValid(grid, visited, i-1, j)) dfs(res, grid, visited, i-1, j, step+1);
22         if(isValid(grid, visited, i, j-1)) dfs(res, grid, visited, i, j-1, step+1);
23         visited[i][j] = false;
24         return;
25     }
26     int uniquePathsIII(vector<vector<int>>& grid) {
27         int res = 0;
28         n=grid.size();
29         m=grid[0].size();
30         w=n*m;
31         vector<vector<bool>> visited(n, vector<bool>(m, false));
32         for(int i=0; i<n; i++) {
33             for(int j=0; j<m; j++) {
34                 if(grid[i][j]==1) {
35                     si=i, sj=j;
36                 } else if(grid[i][j]==2) {
37                     ei=i, ej=j;
38                 } else if(grid[i][j]==-1) {
39                     w--;
40                 }
41             }
42         }
43         
44         dfs(res, grid, visited, si, sj, 1);
45         return res;
46     }
47 };

 

posted @ 2021-01-29 15:05  habibah_chang  阅读(86)  评论(0编辑  收藏  举报