题目:
设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
例如矩阵
中包含一条字符串"bcced
“的路径,但是矩阵中不包含”abcb
"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
输入示例:
"abcesfcsadee", "abcb"
输出示例:
false
规定:
需要注意给出的输入是数组和其行列数,而非直接给出矩阵,所以需要根据行列数将数组转换成矩阵。
解题思路:
思路:
本题采用“回溯法”进行求解,这是一种暴力搜索方法,通过搜索所有可能的结果来解决问题。回溯法在一次搜索结束时通过条件判断是否需要进行回溯,如果不符合条件则需回溯一步,将这一次搜索过程中设置过的状态进行清除,从新的点开始新的搜索过程。如果符合条件则进行更深一步的试探。直至试探成功或回溯到起点时退出,并返回“成功标志”或者转移起点开始新一轮的试探。
【百度百科】 回溯法:是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。
代码:
class Solution {
public:
bool backtracking(vector<vector<char>> &matrix_trans,
vector<vector<int>> &matrix_used,
int row, int col, char *str, int rows, int cols){
if(*str=='\0'){
return true;
}
if(matrix_trans[row][col]==*str){
//相等
matrix_used[row][col]=1;//标记使用
str++;//下一字符
if(*str=='\0'){
return true;
}
//上右下左
if(row-1>=0 && matrix_used[row-1][col]!=1){
if(backtracking(matrix_trans, matrix_used, row-1, col, str, rows, cols)){
return true;
}
}
if(col+1<cols && matrix_used[row][col+1]!=1){
if(backtracking(matrix_trans, matrix_used, row, col+1, str, rows, cols)){
return true;
}
}
if(row+1<rows && matrix_used[row+1][col]!=1){
if(backtracking(matrix_trans, matrix_used, row+1, col, str, rows, cols)){
return true;
}
}
if(col-1>=0 && matrix_used[row][col-1]!=1){
if(backtracking(matrix_trans, matrix_used, row, col-1, str, rows, cols)){
return true;
}
}
//该元素的上下左右都不满足,将该元素标记置0,移位
matrix_used[row][col]=0;//取消标记
return false;
}
else{
return false;//不满足
}
}
bool hasPath(char* matrix, int rows, int cols, char* str)
{
if(*str=='\0'){
return true;
}
vector<vector<char>> matrix_trans(rows);//将输入char数组转为二维数组
vector<vector<int>> matrix_used(rows);//用于标记元素是否已用的二维数组
for(int i=0;i<rows;i++){//行
for(int j=0;j<cols;j++){//列
char * ptr = matrix+i*cols+j;//计算指针偏移量
matrix_trans[i].push_back(*ptr);//取出数据存进二维数组
matrix_used[i].push_back(0);
}
}
int row=0, col=0;//行和列
while(!(((row==rows)&&(col==cols))||*str=='\0')){
for(row=0;row<rows;row++){//行
for(col=0;col<cols;col++){//列
if(matrix_trans[row][col]==*str){
//矩阵元素等于当前字符
if(backtracking(matrix_trans, matrix_used, row, col, str, rows, cols)){
return true;
}
}
}
}
}
return false;
}
};
完整程序:
#include <stdio.h>
#include <vector>
using namespace std;
//code block,上述代码块,填充至此。
int main(){
char matrix[] = "abcesfcsadee";//"AAAAAAAAAAAA";
int rows = 3;
int cols = 4;
char str[] = "abcb";//"AAAAAAAAAAAA";
Solution so;
bool result = so.hasPath(matrix, rows, cols, str);
if(result){
printf("true");
}
else{
printf("false");
}
return 0;
}
输入输出测试:
测试用例1:
输入:
"abcesfcsadee", "abcb"
输出:
false
测试用例2:
输入:
"AAAAAAAAAAAA", "AAAAAAAAAAAA"
输出:
true