思路:利用回溯法;
遍历矩阵,因为遍历过的不可以继续遍历,所以我们需要一个和矩阵一样的辅助数组;
当遍历到节点和目标字符串字符相等时,则分别向上向下向左向右继续遍历,直到目标字符串完全匹配;
如果4个方向均未匹配到,则将该节点设置为未遍历,返回调用出重新遍历其他方向节点;
public class HasPath {
/**
*
* @param matrix:输入的字符串
* @param rows:矩阵化后的行
* @param cols:矩阵化后的列
* @param str:需要匹配的字符串
* @return
*/
public boolean hasPath(char[] matrix, int rows, int cols, char[] str){
//定义一个和数组一样大小的标识数组
int[] flag = new int[matrix.length];
//遍历矩阵
for(int i = 0; i < rows; i ++){
for(int j = 0; j < cols; j ++){
//字符串匹配,如果匹配到就返回true
if(helper(matrix, rows, cols, i, j, str, 0, flag)){
return true;
}
}
}
return false;
}
public static boolean helper(char[] matrix, int rows, int cols, int i, int j, char[] str, int k, int[] flag){
//确定当前字符的位置
int index = i * cols + j;
// i < 0 || i >= rows || j < 0 || j >= cols 这些是矩阵边界值的判断
// matrix[index] != str[k]当前字符必须相等
// flag[index] == 1检查当前节点是否遍历过
if(i < 0 || i >= rows || j < 0 || j >= cols || matrix[index] != str[k] || flag[index] == 1){
return false;
}
//判断是否已经完全匹配
if(k == str.length - 1){
return true;
}
flag[index] = 1;//遍历过的标识为1
//向上遍历
if(helper(matrix, rows, cols, i - 1, j, str, k + 1, flag))
return true;
//向下遍历
if(helper(matrix, rows, cols, i + 1, j, str, k + 1, flag))
return true;
//向左遍历
if(helper(matrix, rows, cols, i, j - 1, str, k + 1, flag))
return true;
//向右遍历
if(helper(matrix, rows, cols, i , j + 1, str, k + 1, flag)){
return true;
}
//如果都不匹配,则将该节点标识为未遍历,返回调用处。
flag[index] = 0;
return false;
}
public void test() {
char[] matrix = "abfgcfcsjdch".toCharArray();
int rows = 3;
int cols = 4;
char[] str = "bfcc".toCharArray();
if (hasPath(matrix, rows, cols, str))
System.out.println("Test5 passed.");
else
System.out.println("Test5 failed.");
}
public static void main(String[] args) {
HasPath demo = new HasPath();
demo.test();
}
}
历矩阵的时候,需要一个额外的空间标识这个元素是否已经被遍历;每次遍历都设置节点向上,向下,向左,向右;
该博客介绍利用回溯法遍历矩阵匹配目标字符串的思路。需一个和矩阵一样的辅助数组,遍历到节点与目标字符相等时,向上下左右继续遍历。若4个方向均未匹配,将节点设为未遍历,返回重新遍历。遍历矩阵时要用额外空间标识元素是否已遍历。
1068

被折叠的 条评论
为什么被折叠?



