通用型题解,回溯经典题

矩阵中的路径

http://www.nowcoder.com/questionTerminal/c61c6999eecb4b8f88a98f66b273a3cc

官方题解中用 '#' 来表示走过的路径,其实不太严谨,万一扫描的字符串路径中有 '#' 字符呢?
java可以用 '\0' 来表示空字符,可以作为扫描过的路径标记
我这里用了一个isVisited布尔类型的数组来标记走过的路径,与扫描的矩阵同等大小
思路很简单,就是根据给定的str路径,然后dfs矩阵,从第一行第一个开始,找属于str的第一个字符,然后搜上下左右,道理都懂,咋实现呢?
必须得说一下这个dfs矩阵
dfs:
参数:矩阵数组,字符串,当前行,当前列,当前扫描的字符下标
终止条件:返回false:数组下标越界、字符不匹配,已扫描过的字符;
返回 true:字符串的下标 为 字符串长度减一,证明已经扫描完字符串了,有了一条完整的路径
标记当前字符证明是走过了
下一步递归:上下左右四个方向依次dfs
回溯:去掉标记,证明此路不通,不走了,返回上一步
返回下一步递归的结果
因为题目中给定的不是二维数组,所以还需要全局变量来记录行数和列数,以及需要一个isVisited数组
代码如下,虽然很长但是一部分一部分的看就不烦了

    // 全局记录行和列的长度
    int rows;
    int cols;
    // 标记是否走过了
    boolean[] isVisited;
    public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
        this.rows = rows;
        this.cols = cols;
        isVisited = new boolean[matrix.length];
        for (int i=0; i<matrix.length; i++) {
            isVisited[i] = false;
        }
        for (int i=0; i<rows; i++) {
            for (int j=0; j<cols; j++) {
                // 如果从某一个点可以搜出来一条路径,就返回true
                if (dfs(matrix, str, i, j, 0)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 深度优先搜索字符矩阵中是否有要找的路径
     * @param matrix 字符矩阵
     * @param str 要找的路径
     * @param row 当前行
     * @param col 当前列
     * @param position 扫描路径中的下标
     * @return 是否符合条件
     */
    boolean dfs(char[] matrix, char[] str, int row, int col, int position) {
        // 首先排除下标越界,访问过了,不符合当前条件
        if (row < 0 || row >= rows || col < 0 || col >= cols || isVisited[row * cols + col] || matrix[row * cols + col] != str[position]) {
            return false;
        }
        // 成功的时候返回
        if (position == str.length - 1) {
            return true;
        }
        // 都不是,标记本路径,并进行下一步递归
        isVisited[row * cols + col] = true;
        // 搜它的上下左右有没有符合的
        boolean result = dfs(matrix, str, row-1, col, position+1) || dfs(matrix, str, row+1, col, position+1)
                || dfs(matrix, str, row, col-1, position+1) || dfs(matrix, str, row, col+1, position+1);
        // 回溯
        isVisited[row * cols + col] = false;
        return result;
    }
全部评论

相关推荐

我就是0offer糕手:北大不乱杀
点赞 评论 收藏
分享
ALEX_BLX:虽然说聊天记录不可信,不过这个趋势确实如此但我觉得也要想到一点就是卷后端的人里真正有“料”的人又有多少,我说的这个料都不是说一定要到大佬那种级别,而是就一个正常的水平。即使是现在也有很多人是跟风转码的,2-3个月速成后端技术栈的人数不胜数,但今时不同往日没可能靠速成进大厂了。这种情况就跟考研一样,你能上考场就已经打败一半的人了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务