问题:
给定一个棋盘,
- 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 };