描述
示例1
输入:[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcced"
复制返回值:true
示例2
输入:[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcb"
复制返回值:false
题解
回溯算法解决,类似于这种棋盘格(矩阵形式)的问题纯for循环很难解出来,就用回溯递归算法。
他是从矩形中的一个点开始往他的上下左右四个方向查找,这个点可以是矩形中的任何一个点,所以代码的大致轮廓我们应该能写出来,就是遍历矩形所有的点,然后从这个点开始往他的4个方向走,因为是二维数组 ,所以有两个for循环
这里关键代码是dfs这个函数,因为每一个点我们都可以往他的4个方向查找,所以我们可以把它想象为一棵4叉树,就是每个节点有4个子节点,而树的遍历我们最容易想到的就是递归
function hasPath( matrix , word ) {
let words = Array.from(word);
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[0].length; j++) {
if (dfs(matrix, words, i, j, 0)) return true; //从[i,j]这个坐标开始查找
}
}
return false;
}
function dfs(matrix, word, i, j, index) {
if (i >= matrix.length || i < 0 || j >= matrix[0].length
|| j < 0 || matrix[i][j] != word[index]) return false;
//如果word的每个字符都查找完了,直接返回true
if (index == word.length - 1) return true;
let tmp = matrix[i][j]; //把当前坐标的值保存下来,为了在最后复原
matrix[i][j] = '.'; //然后修改当前坐标的值
//走递归,沿着当前坐标的上下左右4个方向查找
let res = dfs(matrix, word, i + 1, j, index + 1)
|| dfs(matrix, word, i - 1, j, index + 1)
|| dfs(matrix, word, i, j + 1, index + 1)
|| dfs(matrix, word, i, j - 1, index + 1);
matrix[i][j] = tmp; //递归之后再把当前的坐标复原
return res;
}
module.exports = {
hasPath : hasPath
};
时间复杂度:O(mn*k^3),m和n是矩阵的宽和高,最坏的情况下遍历矩阵的所有位置,k是字符串的长度,下面的dfs我们可以把它看做是一棵4叉树,除了第一次的时候可以往4个方向走,其他情况下只能往3个方向走(进来的那个方向回不去)
空间复杂度:O(K),k是字符串的长度