题目描述:

  请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

  解题思路:

  本题实际并不复杂,是一个可以用回溯法解决的典型题目。所谓回溯法,就是有组织的进行穷举搜索的过程,通过深度优先来对所有可能的解进行穷举。

  首先,遍历整个矩阵,我们可以找到和字符串str首字符相同的单元格,作为查找的起点,然后遍历它的上下左右四个字符,如果有和str下一个字符相同的,就以该单元格作为下一个遍历起点,依次进行,如果没有找到就回退到上一个字符,重新查找其他方向。整个过程是一个非常典型的回溯思路。

  由于回溯法天生的递归特性,路径可以看做一个栈,当在矩阵中定位了路径中前n个字符的位置后,在第n个字符的上下左右(没有遍历过的)格子找第n+1个字符,如果没有找到,只能回退到第n-1个字符,重新定位第n个字符。

  由于路径不能重复进入矩阵的格子,所以还需要一个和矩阵大小相同的布尔矩阵来标识每个单元格是否被访问过,这也是回溯法的惯用方法。

  不难想到,实际上这个过程就对应了一棵树的深度优先遍历,具体可以结合以下代码进一步理解。

  举例:

![](https://img2018.cnblogs.com/blog/1608161/201905/1608161-20190523111233679-1950580055.png)

  编程实现(Java):

public class Solution {
public boolean hasPath(char[] matrix, int rows, int cols, char[] str){
//回溯法搜索
if(matrix==null||rows<1||cols<1||str==null)
return false;
char[][] mat=new char[rows][cols];
boolean[][] flags=new boolean[rows][cols]; //标记每个节点是否已经访问过
for(int i=0;i<rows;i++){ //转化为矩阵
for(int j=0;j<cols;j++){
mat[i][j]=matrix[cols*i+j];
flags[i][j]=false;
}
}
//以上是数据准备,下面开始搜索
//从每个元素依次开始搜索
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){ //以mat[i][j]开始
if(hasPath(mat,i,j,rows,cols,flags,str,0)==true) //找到了返回真
return true;
}
}
return false;
}
boolean hasPath(char[][] mat,int i,int j,int rows, int cols,boolean[][] flags,char[] str,int start){ //以mat[i][j]开始搜索
if(start==str.length) //str元素已经遍历完
return true;
if(i<0||i>=rows||j<0||j>=cols) //i,j超出范围
return false;
boolean res=false;
//i,j在范围内
if(mat[i][j]==str[start] && flags[i][j]==false) { //当前相等
flags[i][j]=true;
++start;
//上下左右四个方向查找
res=hasPath(mat,i-1,j,rows,cols,flags,str,start)||
hasPath(mat,i+1,j,rows,cols,flags,str,start) ||
hasPath(mat,i,j-1,rows,cols,flags,str,start) ||
hasPath(mat,i,j+1,rows,cols,flags,str,start);
if(res==false){ //没有找到,回溯
--start;
flags[i][j]=false;
}
}
return res;
} }

最新文章

  1. CentOS7安装ftp服务器
  2. 先贴上代码:Random快排,快排的非递归实现
  3. 国产AR SDK介绍
  4. 如何给magento的产品页面添加返回按钮
  5. TLS学习总结
  6. Ejabberd源码解析前奏--概述
  7. php模板引擎
  8. 刷新dns
  9. POJ 1470 Closest Common Ancestors(LCA&amp;RMQ)
  10. RPO(Relative Path Overwrite)
  11. 加载Excel时,如何过滤空行空列
  12. oracle汉字转拼音(获得全拼/拼音首字母/拼音截取等)
  13. Linux下系统时间函数、DST等相关问题总结(转)
  14. subordinate clause/从句
  15. FIFO IP核仿真
  16. vip导致的serverConnection closed by foreign host问题
  17. linux第一次实验报告
  18. 个推基于 Apache Pulsar 的优先级队列方案
  19. go 切片
  20. 实现一个 RESTful API 服务器

热门文章

  1. Erlang下与其他程序和语言的通信机制(3)
  2. iOS开发之剖析&amp;quot;秘密&amp;quot;App内容页面效果(一)
  3. python多线程实现抓取网页
  4. POJ2393 Yogurt factory 【贪心】
  5. oc80--copy
  6. SQLServer添加链接服务器
  7. B2761 [JLOI2011]不重复数字 离散化
  8. IDEA Spark程序报错处理
  9. Linux分区方式 及 Xshell远程连接排错
  10. ural 1009. K-based Numbers(简单dp)