剑指 Offer 12. 矩阵中的路径

剑指 Offer 12. 矩阵中的路径

推荐写法

把判断条件都写在dfs函数开头(对节点进行处理,尽量不要对边进行处理)

写法一

class Solution {
    boolean[][] vis;

    public boolean exist(char[][] board, String word) {
        int m = board.length, n = board[0].length;
        vis = new boolean[m][n];
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(dfs(board, i, j, word, 0)) return true;
            }
        }
        return false;
    }

    boolean dfs(char[][] board, int x, int y, String word, int ind){
        if(x < 0 || x >= board.length || y < 0 || y >= board[0].length || vis[x][y] || board[x][y] != word.charAt(ind)) return false;
        if(ind == word.length() - 1) return true;

        vis[x][y] = true;
        if(dfs(board, x + 1, y, word, ind + 1)) return true;
        if(dfs(board, x - 1, y, word, ind + 1)) return true;
        if(dfs(board, x, y + 1, word, ind + 1)) return true;
        if(dfs(board, x, y - 1, word, ind + 1)) return true;
        vis[x][y] = false;

        return false;
    }
}

写法二

for循环

class Solution {
    int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    boolean[][] vis;

    public boolean exist(char[][] board, String word) {
        int m = board.length, n = board[0].length;
        vis = new boolean[m][n];
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(dfs(board, i, j, word, 0)) return true;
            }
        }
        return false;
    }

    boolean dfs(char[][] board, int x, int y, String word, int ind){
        int m = board.length, n = board[0].length;
        if(x < 0 || x >= m || y < 0 || y >= n || vis[x][y] || board[x][y] != word.charAt(ind)) return false;
        if(ind == word.length() - 1) return true;

        vis[x][y] = true;
        for(int i = 0; i < dir.length; i++){
            int nx = x + dir[i][0];
            int ny = y + dir[i][1];
            if(dfs(board, nx, ny, word, ind + 1)) return true;
        }
        vis[x][y] = false;

        return false;
    }
}

之前写法

解法一和解法二 vis数组 写法不同。

解法一处理的是节点,即进入该节点后,更改当前节点的访问状态。

解法二处理的是,即进入该节点前,更改即将进入节点的访问状态。

需要注意的是,两种写法不要混淆。

解法一

class Solution {
    int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    boolean[][] vis;

    public boolean exist(char[][] board, String word) {
        int m = board.length, n = board[0].length;
        vis = new boolean[m][n];
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(backtrack(board, i, j, word, 0)) return true;
            }
        }
        return false;
    }

    boolean backtrack(char[][] board, int x, int y, String word, int ind){
        int m = board.length, n = board[0].length;
        if(board[x][y] != word.charAt(ind)) return false;
        if(ind == word.length() - 1) return true;

        vis[x][y] = true;
        for(int i = 0; i < dir.length; i++){
            int nx = x + dir[i][0];
            int ny = y + dir[i][1];
            if(nx < 0 || nx >= m || ny < 0 || ny >= n || vis[nx][ny]) continue;
            if(backtrack(board, nx, ny, word, ind + 1)) return true;
        }
        vis[x][y] = false;

        return false;
    }
}

解法二

class Solution {
    int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    boolean[][] vis;

    public boolean exist(char[][] board, String word) {
        int m = board.length, n = board[0].length;
        vis = new boolean[m][n];
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                vis[i][j] = true;
                if(backtrack(board, i, j, word, 0)) return true;
                vis[i][j] = false;
            }
        }
        return false;
    }

    boolean backtrack(char[][] board, int x, int y, String word, int ind){
        int m = board.length, n = board[0].length;
        if(board[x][y] != word.charAt(ind)) return false;
        if(ind == word.length() - 1) return true;

        for(int k = 0; k < dir.length; k++){
            int nx = x + dir[k][0];
            int ny = y + dir[k][1];
            if(nx < 0 || nx >= m || ny < 0 || ny >= n || vis[nx][ny]) continue;
            vis[nx][ny] = true;
            if(backtrack(board, nx, ny, word, ind + 1)) return true;
            vis[nx][ny] = false;
        }

        return false;
    }
}

你可能感兴趣的:(#,剑指offer,算法)