zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    TypeError: can't compare offset-naive and offset-aware datetimes bugfix
    pg_restore数据库恢复指令
    第四十期百度技术沙龙笔记整理
    JS事件模型小结
    matlab Newton method
    Markdown 语法的简要规则
    iOS社交分享Twitter、Facebook、拷贝到剪切板、LINE、及邮件
    Linux系统调用过程分析
    iOS自己定义返回button(不影响返回手势)
    MAVEN项目模块化
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14345052.html
Copyright © 2011-2022 走看看