判断输入的字符串是否为矩阵中的路径(dfs+回溯)

import java.util.Scanner;
public class Main12 {
    
    private static Boolean findPath(String[] matrix, String str, int row,int col) {
        //边界判断
        if (matrix.length != row*col || row <= 0 || col <= 0 || matrix.length <= 0 || str.length() <=0 ||matrix.length < str.length())
            return false;
        //遍历一维矩阵
        for (int i = 0; i < matrix.length; i++) {
            //dfs
            //1.定义dfs规则
            int[] standard = {-col,col,-1,1};//上下左右(一维值对应二维位置)
            //2.定义回溯记录
            //dfs到该点,将该点置为已访问,后续发现递归dfs时走不通,则需要回溯到上一个点,此点重置为未访问
            boolean[] visited = new boolean[matrix.length];
            int index = i;
            if (dfs(matrix,str,index,0,visited,standard)){
                //比如,输入"abtg",而且dfs规则为(右上左下),这样从a开始dfs一次性递归成功
                return true;//从一个点出发(i),递归dfs成功,则匹配到
            }
            //该点未递归dfs成功,再从下一个矩阵点递归
        }
        return false;
    }

    private static boolean dfs(String[] matrix, String str, int index, int k, boolean[] visited, int[] standard) {
        boolean flag = false;
        //相同才继续dfs
        if (matrix[index].equals(String.valueOf(str.charAt(k)))){
            //判断是否到头了
            if (k == str.length()-1)
                return true;
            //置为已访问(试探性),不行再回溯
            visited[index] = true;
            //上下左右递归dfs
            for (int i = 0; i < 4; i++) {
                //先判断递归边界条件,下一个dfs点不能越界矩阵,且未走过
                if (index + standard[i] >= 0 && index + standard[i] < matrix.length && visited[index+standard[i]] == false){
                    flag = dfs(matrix,str,index+standard[i],++k,visited,standard);
                    //递归到底,上下左右任意一个满足dfs,立即终止,return true,说明找到了
                    if (flag){
                        break;
                    }
                    //递归到底,没找到,k--回到上个str[k]
                    --k;
                }
            }
            //四个方向都不走不通,此点不行,需回溯
            visited[index] = false;
        }
        return flag;
    }

    private static String[] secondDimensionToOne(String[][] strArr) {
        /**
         * 二维矩阵i,j表示上下左右
         *               (i-1)*col+j
         *    i*col+j-1    i*col+j    i*col+j+1
         *               (i+1)*col+j
         *
         *
         * 一维矩阵用index表示,[0,1,2 ----,index]
         *
         * 可以用一维矩阵表示二维(比如在3*4的二维矩阵中,一维矩阵的index=7,对应的二维矩阵上下左右用下面公式)
         *               index-col
         *        index-1 index  index+1
         *               index+col
         */
        int row = strArr.length;
        int col = strArr[0].length;
        String[] matrix = new String[row*col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                matrix[i*col+j] = strArr[i][j];
            }
        }
        return matrix;
    }

    public static void main(String[] args) {
        String[][] strArr = {{"a","b","t","g"},{"c","f","c","s"},{"j","d","e","h"}};
        Scanner sc = new Scanner(System.in);
        String  str = sc.next();
        String[] matrix = secondDimensionToOne(strArr);//二维矩阵变一维矩阵
        Boolean b = findPath(matrix, str,strArr.length,strArr[0].length);
        System.out.println(b);
    }
}

猜你喜欢

转载自blog.csdn.net/tmax52HZ/article/details/107634718