Although this is a matrix problem, but it cannot be done by BFS, following is my solution, but it doesn't work when the test case is:

[["A","B","C","E"],

 ["S","F","E","S"],

 ["A","D","E","E"]]

"ABCESEEEFS"

Because, the E (1, 2) was visited two times, the first time, it was visited after C (0, 2); the second time, it was visited after S (1, 3).

When E(1, 2) was visited second time, it was skipped over.

class Solution {
    boolean res = false;
    int m, n;
    private boolean[][] visited;
    public boolean exist(char[][] board, String word) {
        
        if(board==null || board.length==0)
            return false;
         m = board.length;
        n = board[0].length;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(board[i][j]==word.charAt(0)){
                    visited = new boolean[m][n];
                    if(bfs(board, word, i, j))
                        return true;
                }
            }
        }
        
        return false;
    }
    
    private int[][] dirs={{0,1},{0,-1},{-1,0},{1,0}};
    private boolean bfs(char[][] board, String word, int i, int j){
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{i, j});
        int index = 1;
        while(!queue.isEmpty()){
            if(word.length()==index)
                return true;
            int size = queue.size();
            boolean findNext = false;
            for(int k=0;k<size;k++){
                int[] cell = queue.poll();
                for(int[] dir:dirs){
                    int x = cell[0]+dir[0];
                    int y = cell[1]+dir[1];
                    if(!check(board, x, y))
                        continue;
                    if(!visited[x][y] && board[x][y]==word.charAt(index)){
                        queue.offer(new int[]{x,y});
                        findNext = true;
                    }
                }
            }
            if(findNext)
                index++;
        }
        return false;
    }
    
    private boolean check(char[][] board, int i, int j){
        if(i<0||i>=m||j<0||j>=n)
            return false;
        return true;
    }
}

So this problem cannot be done by BFS.

-------------------------------------------------

The following is the DFS solutiom, it works well.

Time complexity: O(m*n*3L), where L is the length of the word.

  • For the backtracking function, initially we could have at most 4 directions to explore, but further the choices are reduced into 3 (since we won't go back to where we come from.

Space complexity: O(L), where L is the length of the word.

  • The main consumption of the memory lies in the recursion call of the dfs(backtracking) function.
  • The maximum length of the call stack would be the length of the word. 
class Solution {
    boolean res = false;
    int m, n;
    private boolean[][] visited;
    public boolean exist(char[][] board, String word) {
        if(board==null || board.length==0)
            return false;
        m = board.length;
        n = board[0].length;
        visited = new boolean[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(board[i][j]==word.charAt(0)){
                    dfs(board, word, i, j, 0);
                }
            }
        }
        return res;
    }
    
    private int[][] dirs={{0,1},{0,-1},{-1,0},{1,0}};
    private void dfs (char[][] board, String word, int x, int y, int index){ 
        if(word.length()-1==index){
            res = true;
            return;
        }
        visited[x][y]=true;
        for(int[] dir: dirs){
            int p = x+dir[0];
            int q = y+dir[1];
            if(check(board, p, q) && !visited[p][q] && board[p][q] == word.charAt(index+1)){
                dfs(board, word, p, q, index+1);
            }
        }
        visited[x][y]=false;
    }
    
    private boolean check(char[][] board, int i, int j){
        if(i<0||i>=m||j<0||j>=n)
            return false;
        return true;
    }
}

 

posted on 2022-03-08 12:56  阳光明媚的菲越  阅读(38)  评论(0编辑  收藏  举报