经典回溯问题。

选择使用循环+递归的方式进行回溯。

在一个循环内遍历矩阵中的结点,以该点为起点调用寻路函数
在寻路函数中,先判断当前字符串是否满足要求,若是则返回true,否则将其周围四个点拼接至当前字符串尾部,递归调用寻路函数。

为了避免一个字符被多次使用,引入一个visited数组,用于记录被访问过的点。

为了对递归进行剪枝,当当前要拼接的字符与要求的字符串中对应位置的字符不等时,直接返回false。当要访问的结点位置越界时直接返回false。当当前字符串长度大于要求字符串时直接返回false。

这里面在构造visited数组时复习了一下vector的初始化方法。

vector<bool> temp(matrix.at(0).size(),false);
vector<vector<bool>> visited(matrix.size(), temp);

这种vector(x, y)的初始化方法,第一个参数x指定vector的大小,系统会直接为vector分配x*sizeof(T)的空间,即直接在该数组中预建x个元素,当然,之后如果添加新的元素,系统会自动为其分配新的空间,这里不影响vector的动态特性。第二个y指定了这x个元素以什么值进行初始化,比如这个例子中,第一行是将matrix.at(0).size()个元素全部初始化为false,而第二行则是将matrix.size()个元素全部初始化为temp。这种初始化方法虽然不常用,但是用起来还是很方便的。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix char字符型vector<vector<>> 
     * @param word string字符串 
     * @return bool布尔型
     */
    bool hasPath(vector<vector<char> >& matrix, string word) {
        // write code here
        if(!matrix.size() || !matrix.at(0).size()){
            return false;
        }
        vector<bool> temp(matrix.at(0).size(),false);
        vector<vector<bool>> visited(matrix.size(), temp);
        for(int i = 0;i < matrix.size();i++){
            for(int j = 0;j < matrix.at(0).size();j++){
                if(findRoad(matrix, visited, word, "", i, j, 0)){
                    return true;
                }
            }
        }
        return false;
    }
    bool findRoad(vector<vector<char>> mat, vector<vector<bool>>& visited, string word, string str, int row, int col, int len){
        if(row < 0 || col < 0 || row > mat.size() - 1 || col > mat.at(0).size() - 1 || visited.at(row).at(col) || len > word.size() - 1 || word[len] != mat.at(row).at(col)){
            return false;
        }
        else{
            string temp = str + mat.at(row).at(col);
            if(temp == word){
                return true;
            }
            visited.at(row).at(col) = true;
            int ur = row - 1;
            int lc = col - 1;
            int rc = col + 1;
            int dr = row + 1;
            if(findRoad(mat, visited, word, temp, ur, col, len + 1) || findRoad(mat, visited, word, temp, row, lc, len + 1) || findRoad(mat, visited, word, temp, row, rc, len + 1) || findRoad(mat, visited, word, temp, dr, col, len + 1)){
                return true;
            }
            else{
                visited.at(row).at(col) = false;
                return false;
            }
        }
    }
};