剑指 Offer 12: 矩阵中的路径

这道题看着简直是完全没思路,看了下发现是使用回溯的方法。

下面这里要注意,newi是旧的i加上新的偏移值!newj同理,并不是加自己,别昏头!

剑指 Offer 12: 矩阵中的路径_第1张图片

s是String类型的变量,要写成size()

剑指 Offer 12: 矩阵中的路径_第2张图片

下面是正确的代码:

class Solution {
    public boolean exist(char[][] board, String word) {
        //每一个节点都可能是开始的节点
        int h = board.length, w = board[0].length;
        //千万记住不能忘记写boolean类型的数组new出大小,默认值是false
        boolean[][] visited = new boolean[h][w];
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
        //有多次机会,所以不可以直接返回值,对了或者循环结束了才能返回
                boolean flag = check(board,word,visited,i , j, 0);
                if(flag)
                    return true;
            }
        }
        return false;
    }
    //传进来的k是已经查对的位数
    public boolean check(char[][] board,String s, boolean[][] visited,int i, int j,int k){
        //有两种特殊情况,一种是不等于说明不满足条件
        if(board[i][j] != s.charAt(k))
            return false;
        //另一种是此时也相等并且等于s的长度
        else if(k == s.length() - 1)
            return true;
        //开始回溯的部分,每个节点有上下左右四个方向
        int [][] directions = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
        visited[i][j] = true;
        boolean result = false;
        for(int[] dic : directions){
            //按照上下左右的方式递增值
            int newi = dic[0] + i,newj  = dic[1] + j;
            if(newi>=0&&newi=0&&newj

2023/8/3

再看这道题的时候还是有点模糊,记住是套回溯法的模板,先定义一个双重循环,试用每个点作为开始节点,然后由于是要判断多个,所以false了还要继续,true了就可以直接返回。并且要使用一个拥有四个方位的数组,按照循环每一个试一遍。

剑指 Offer 12: 矩阵中的路径_第3张图片

剑指 Offer 12: 矩阵中的路径_第4张图片 

 下面是正确的代码,考虑了撤销回溯的类型,并且绝对不能使用或,这样不方便寻找每一个节点的信息,也不方便撤销回溯。并且flag的使用要考虑到实际情况,在回溯中除了错误或者不相等时可以返回,其他情况下仍要继续(往四个方向的),并且这里实际上没有递归,当找到了true时这个值是给了flag,所以直接返回的result就是以某个节点为起始点的最终结果。

class Solution {

    public boolean exist(char[][] board, String word) {

        int max_High = board.length, max_Length = board[0].length;

        boolean[][] visited = new boolean [max_High][max_Length];

        int [][] dic = {{0,1},{1,0},{-1,0},{0,-1}};

        //visited判断是否走过,走过就要跳过,没走过就撤销

        //以每一个节点为起点

        for(int i = 0; i < max_High; i++){

            for(int j = 0; j < max_Length; j++){

                boolean flag;

                flag = check(dic,board,visited,i,j,0,word,max_High,max_Length);

                if(flag)    return true;

            }

        }

        return false;

    }

//首先判断当前是不是,不是就返回->撤销;再判断还剩几个,count指的是已经符合几个了

    public boolean check(int[][] dic,char[][] board, boolean[][] visited, int i, int j, int count, String word,int max_High, int max_Length){

        //越界说明这个分支肯定是错的

        if(board[i][j] != word.charAt(count))

            return false;

        if(count == word.length() - 1)//说明已经成功找到

            return true;

        visited[i][j] = true;

        boolean result = false;//必不可少

        // boolean flag = check(board,visited,i+1,j,count+1,word,max_High,max_Length)||

        // check(board,visited,i-1,j ,count+1,word,max_High,max_Length) ||

        // check(board,visited,i,j+1 ,count+1,word,max_High,max_Length) ||

        // check(board,visited,i,j-1 ,count+1,word,max_High,max_Length);

        for(int[] temp : dic){

            // boolean flag = false;

            int newi = i + temp[0]; int newj = j + temp[1];

            if(newi < max_High && newi >= 0 && newj < max_Length && newj >= 0 && !visited[newi][newj]){

                boolean flag = check(dic,board,visited,newi,newj,count+1,word,max_High,max_Length);

            if(flag){

                result = true;

                break;

            }

        }

    }

        visited[i][j] = false;//没找到,撤销

        return result;

    }

}

你可能感兴趣的:(#,剑指offer,矩阵,算法,线性代数)