2019.3.4 《剑指Offer》从零单刷个人笔记整理(66题全)目录传送门
以前没有做过回溯法的题目,没有经验。一开始以为是一道图的问题,开始尝试用DFS的思想做。把矩阵想象成一个稠密图,直接用矩阵存储每一个结点,在每一个点上下左右找符合的邻接点,从每一个入口结点开始进行遍历,找出所有符合输入深度的路径进行验证。这样思考貌似可以做,但是区别在于,这种用于遍历满足某一深度的所有可能路径,当题目其实给的是一条特定的路径。
其实思想已经很接近了,只要在这个遍历的基础上加入“剪枝”的思想,提前检查并排除所有不可能的路径,其实就是回溯法了。
回溯法的关键在于递归,递归的深度就是目标字符串的长度,每一层遍历都先进行检查,只走能走的路。
题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
Java实现:
/**
*
* @author ChopinXBP
* 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。
* 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。
* 如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。
* 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,
* 因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
*
*/
public class HasPath_64 {
public static void main(String[] args) {
// TODO Auto-generated method stub
char[] matrix = {'A','B','C','E','S','F','C','S','A','D','E','E'};
char[] str = {'A','B','C','B'};
System.out.println(hasPath(matrix, 3, 4, str));
}
public static boolean hasPath(char[] matrix, int rows, int cols, char[] str)
{
if(matrix == null || str == null || str.length == 0)return false;
int length = matrix.length;
if(matrix.length == 0 || rows * cols != length || str.length > length)return false;
boolean[] ispass = new boolean[length];
for(int i = 0; i < length; i++) {
if(Solution(i, 0, matrix, cols, str, ispass)) return true;
}
return false;
}
public static boolean Solution(int idx, int loc, char[] matrix, int cols, char[] str, boolean[] ispass){
if(idx < 0 || idx >= matrix.length || matrix[idx] != str[loc] || ispass[idx]) return false;
if(loc == str.length - 1)return true;
ispass[idx] = true;
if(Solution(idx - 1, loc + 1, matrix, cols, str, ispass)
|| Solution(idx + 1, loc + 1, matrix, cols, str, ispass)
|| Solution(idx - cols, loc + 1, matrix, cols, str, ispass)
|| Solution(idx + cols, loc + 1, matrix, cols, str, ispass))
return true;
ispass[idx] = false; //将标志位恢复
return false;
}
}
C++实现示例:
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str)
{
if(str==NULL||rows<=0||cols<=0)
return false;
bool *isOk=new bool[rows*cols]();
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
if(isHsaPath(matrix,rows,cols,str,isOk,i,j))
return true;
}
return false;
}
bool isHsaPath(char *matrix,int rows,int cols,char *str,bool *isOk,int curx,int cury)
{
if(*str=='\0')
return true;
if(cury==cols)
{
curx++;
cury=0;
}
if(cury==-1)
{
curx--;
cury=cols-1;
}
if(curx<0||curx>=rows)
return false;
if(isOk[curx*cols+cury]||*str!=matrix[curx*cols+cury])
return false;
isOk[curx*cols+cury]=true;
bool sign=isHsaPath(matrix,rows,cols,str+1,isOk,curx-1,cury)
||isHsaPath(matrix,rows,cols,str+1,isOk,curx+1,cury)
||isHsaPath(matrix,rows,cols,str+1,isOk,curx,cury-1)
||isHsaPath(matrix,rows,cols,str+1,isOk,curx,cury+1);
isOk[curx*cols+cury]=false;
return sign;
}
};
#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#