码迷,mamicode.com
首页 > 其他好文 > 详细

矩阵中的路径——剑指offer

时间:2020-09-07 19:08:03      阅读:64      评论:0      收藏:0      [点我收藏+]

标签:board   起点   判断   来源   nbsp   lse   情况   ems   dfs   

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的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 }

 

矩阵中的路径——剑指offer

标签:board   起点   判断   来源   nbsp   lse   情况   ems   dfs   

原文地址:https://www.cnblogs.com/sbb-first-blog/p/13574945.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!