79. Word Search

class Solution {
    public boolean exist(char[][] board, String word) {
      int n = board.length;
      int m = board[0].length;
      boolean[][] visited = new boolean[n][m];
      
      for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
          if(word.charAt(0) == board[i][j] && dfs(board, word, i, j, 0, visited)){
            return true;
          }
        }
      }
      return false;
    }
    
    private boolean dfs(char[][] board, String word, int i, int j, int index, boolean[][] visited){
      if(index == word.length()){
        return true;
      }
      
      if( i < 0 || j < 0 || i >= board.length || j >= board[0].length || board[i][j] != word.charAt(index) || visited[i][j]){
        return false;
      }
      
      visited[i][j] = true;
      if(dfs(board, word, i + 1, j , index + 1, visited) ||
         dfs(board, word, i - 1, j , index + 1, visited) ||
         dfs(board, word, i, j - 1 , index + 1, visited) ||
         dfs(board, word, i, j + 1 , index + 1, visited) ){
        return true;
      }
      visited[i][j] = false;
      return false;
    }
}

 

class Solution {
    private int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    public boolean exist(char[][] board, String word) {
        // sanity check 
        if(board == null || word == null || word.length() == 0) return false;
        int n = board.length;
        int m = board[0].length;
        boolean[][] visited = new boolean[n][m];
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(dfs(i, j, board, word, 0, n, m, visited)) return true;
            }
        }
        return false;
    }
    private boolean dfs(int i, int j, char[][] board, String word, int start, int n, int m, boolean[][] visited){
        if(board[i][j] != word.charAt(start)) return false;
        if(start + 1 == word.length()) return true;
        
        visited[i][j] = true;
        for(int[] dir : dirs){
            int x = i + dir[0];
            int y = j + dir[1];
            // check boundary 
            if(x < 0 || y < 0 || x >= n || y >= m || visited[x][y]) continue;
            if(dfs(x, y, board, word, start + 1, n, m, visited)) return true;
        }
        visited[i][j] = false;
        return false;
        
    }
}

 

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.



idea:
nums = ABCCED for example, traverse the board, if we found nums[0] is on the board[i][j]. do dfs from this i, j 
if dfs returns true, return true;

if after the for loop traversing the whole board, we still havent returned true yet, return false;

nice coding style is put these two conditions together , if both satisfy, return true if(word.charAt(0) == board[i][j] && dfs(board, word, i, j, 0, visited)){ return true;


after the for for loop , if hasn't returned true yet, we return false.


dfs
ending condition is when the length of the nums is reached, return true
because we checked if a letter on the board matches with the letter in a word
at this line of code

 if( i < 0 || j < 0 || i >= board.length || j >= board[0].length || board[i][j] != word.charAt(index) || visited[i][j]){
        return false;
      }
so we when reach the end of the word, we know all the chars match.



if one of the 4 dirs dfs returns true, then return true

if(dfs(board, word, i + 1, j , index + 1, visited) ||
         dfs(board, word, i - 1, j , index + 1, visited) ||
         dfs(board, word, i, j - 1 , index + 1, visited) ||
         dfs(board, word, i, j + 1 , index + 1, visited) ){
        return true;//////////////


if none of the dirs return true, after done with all the call stack's dfs, we return false

      if(dfs(board, word, i + 1, j , index + 1, visited) ||
         dfs(board, word, i - 1, j , index + 1, visited) ||
         dfs(board, word, i, j - 1 , index + 1, visited) ||
         dfs(board, word, i, j + 1 , index + 1, visited) ){
        return true;
      }
      visited[i][j] = false;
      return false;///////////




   visited[i][j] = true; ///////////////
      if(dfs(board, word, i + 1, j , index + 1, visited) ||
         dfs(board, word, i - 1, j , index + 1, visited) ||
         dfs(board, word, i, j - 1 , index + 1, visited) ||
         dfs(board, word, i, j + 1 , index + 1, visited) ){
        return true;
      }
      visited[i][j] = false;/////////////
      return false;
    }

after coordinate i, j, we explore 4 dirs, and if none of them returns true, we know path to the point i, j doesn't work
so we need to backtrack to other three points which are on the same sibling level of i,j . in order to start a new path , we need to
set visited[i][j] as not visited yet for the new path, which might come to point i,j from a different path later
. need to return false to tell people that the paths starting from i,j doesnt work . this is used on both local level and also
a bigger level, bigger level is that i,j is the point on the board we first encountered in the for loop, when we try to try every point
on the board,

local level is, when some prefix works, later, after exploring , we dont find any matchin chars anymore, so we set one visited[i][j] back
to unvisited for exploring other local path with the same prefix



===================================

backtracking steps are still on the paper , visualization steps helps for understanding the backtracking recovery and how its done step by step




posted on 2018-07-18 08:10  猪猪&#128055;  阅读(86)  评论(0)    收藏  举报

导航