• 矩阵中的路径——剑指offer


    请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。

    [["a","b","c","e"],
    ["s","f","c","s"],
    ["a","d","e","e"]]

    但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。

    示例 1:

    输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
    输出:true
    示例 2:

    输入:board = [["a","b"],["c","d"]], word = "abcd"
    输出:false
    提示:

    1 <= board.length <= 200
    1 <= board[i].length <= 200

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    解题思路来源:

    作者:jyd

    链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/solution/mian-shi-ti-12-ju-zhen-zhong-de-lu-jing-shen-du-yo/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    解题思路:
    本问题是典型的矩阵搜索问题,可使用 深度优先搜索(DFS)+ 剪枝 解决。

    算法原理:
    深度优先搜索: 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。

    剪枝: 在搜索中,遇到 这条路不可能和目标字符串匹配成功 的情况(例如:此矩阵元素和目标字符不同、此元素已被访问),则应立即返回,称之为 可行性剪枝 。

     

     

     

     

     

     

     

     

     

     参考代码来源:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/solution/dfsshou-lian-du-by-xie-xin-k/

    非法re:false
    字符不同re:false
    匹配结束re:true
    没结束就分头找
    找到re:true
    没找到re:false

     1 bool exist(char** board, int boardSize, int* boardColSize, char* word){
     2     //bfs深度搜索算法
     3     bool dfs(int i,int j,int k)
     4     {
     5         //是否越界
     6         if(i==boardSize||i<0||j==boardColSize[i]||j<0)
     7         {
     8             return false;
     9         }
    10         //是否相等
    11         if(board[i][j]!=word[k])
    12         {
    13             return false;
    14         }
    15         //是否最后一位
    16         if(k==strlen(word)-1)
    17         {
    18             return true;
    19         }
    20         //没越界、相等且不是最后一位
    21         //标记当前位置继续查
    22         board[i][j]+=30;
    23         //四个分开写,避免正确结果已经出现时还要排查
    24         if(dfs(i+1,j,k+1))
    25         {
    26             return true;
    27         }
    28         if(dfs(i-1,j,k+1))
    29         {
    30             return true;
    31         }
    32         if(dfs(i,j-1,k+1))
    33         {
    34             return true;
    35         }
    36         if(dfs(i,j+1,k+1))
    37         {
    38             return true;
    39         }
    40         board[i][j]-=30;
    41         return false;
    42     }
    43 
    44     if(word==NULL||board==NULL)
    45     {
    46         return false;
    47     }
    48     //枚举起点
    49     for(int i=0;i<boardSize;i++)
    50     {
    51         for(int j=0;j<boardColSize[i];j++)
    52         {
    53             if(dfs(i,j,0))
    54             {
    55                 return true;
    56             }
    57         }
    58     }
    59     return false;
    60     
    61 }

    参考代码来源:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/solution/cshen-du-you-xian-sou-suo-dfsjian-zhi-fu-zhu-shi-b/

     1 //深度优先搜索DFS+剪枝,深度优先搜索:可以理解为暴力法遍历矩阵中所有字符串可能性。DFS通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。剪枝:在搜索中遇到这条路不可能和目标字符串匹配成功的情况(例如:此矩阵元素和目标字符不同、此元素已被访问),则应立即返回,称之为可行性剪枝。
     2 
     3 //DFS算法先判断该位置是否越界,同时该位置是否满足在指定路径的条件,满足则继续判断,不满足返回false,将该位置置为非字母后,递归四个方向的情况,再将该位置还原并返回结果
     4 bool dfs(char** board, int boardSize, int* boardColSize, char* word,int row,int col,int len){
     5     //边界判断,以及判断该位置是否在指定路径上
     6     if(row >= boardSize || row < 0 || col >= *boardColSize || col < 0 || board[row][col] != word[len]){
     7         return false;
     8     }
     9     //判断是否以及完成了路径,完成路径说明矩阵中存在满足条件的路径,返回true
    10     if(len == strlen(word) - 1){
    11         return true;
    12     }
    13 
    14     //将该位置置为非字母,目的是递归的时候不会出现再次进入该位置的情况
    15     char temp = board[row][col];
    16     board[row][col] = '/';
    17     //向上下左右四个方向分别进行递归判断,判断四个方向是否存在满足指定路径的下一个节点的位置
    18     bool res = dfs(board,boardSize,boardColSize,word,row,col+1,len+1) || dfs(board,boardSize,boardColSize,word,row+1,col,len+1) || 
    19               dfs(board,boardSize,boardColSize,word,row,col-1,len+1) || dfs(board,boardSize,boardColSize,word,row-1,col,len+1);
    20     //将该位置还原(回溯过程)
    21     board[row][col] = temp;
    22 
    23     return res;
    24 }
    25 
    26 bool exist(char** board, int boardSize, int* boardColSize, char* word){
    27     for(int i=0;i<boardSize;i++){
    28         for(int j=0;j<*boardColSize;j++){
    29             //对每一个位置进行判断,只要出现一次路径成功遍历的情况,则直接返回true
    30             if(dfs(board,boardSize,boardColSize,word,i,j,0)){
    31                 return true;
    32             }
    33         }
    34     }
    35 
    36     //如果遍历整个矩阵都不存在能完成指定路径的方法,返回false
    37     return false;
    38 }
  • 相关阅读:
    使用jquery.mobile和WebSQL实现记事本功能
    jqprint的网页打印,打印预览可以包含图片
    JDBC--处理Blob
    JDBC--DAO设计模式
    JDBC--使用beanutils工具类操作JavaBean
    JDBC--利用反射及JDBC元数据编写通用的查询方法
    JDBC--PreparedStatement使用
    JDBC--Statement使用
    JDBC--获取数据库连接
    Oracle笔记--PL/SQL(Procedure Language & Structured Query Language)
  • 原文地址:https://www.cnblogs.com/sbb-first-blog/p/13574945.html
Copyright © 2020-2023  润新知