79. Word Search/212. Word Search II--图的back tracking -- tier tree 待续

79题,

给你一个二维的board, 只能往上下左右四个方向走,为你是否能找到单词。

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.

分析: 算法并不难,从每个(i,j)为起点进行dfs, dfs 过程往上下左右四个方向走, 但不能走重复的节点,因此需要设置visted 来标记是否走过。
key point: 用visted 标记后,每次dfs 完后, 记得 visted 需要改成原来的value, 所谓的back tracking 就是体现在这里。


程序被我一开始写的太渣了:

class Solution {
    public boolean exist(char[][] board, String word) {
        
        int row = board[0].length;
        int col = board.length;
        
        
         boolean[][] visted = new boolean[col][row];
        for(int i=0; i<col; i++){
            for(int j=0; j<row; j++){
               // System.out.println("start: "+ i+ " "+ j);
               
                if(dfs(i,j,board,visted,word,0)) return true;
                visted[i][j] = false;
            }
        }
        return false;
           
    }
    
    private boolean dfs(int i, int j, char[][] board, boolean[][] visted, String word, int depth){

                

        if(board[i][j] != word.charAt(depth)) return false;

        if(depth == word.length()-1){
            return true;
        }
        
        boolean flag = false;
        
        visted[i][j] = true;
        //System.out.println(i+ " "+ j);
        //System.out.println(depth);
      
        
        //up
        if(i-1>=0&& !visted[i-1][j]){
            flag = flag || dfs(i-1,j,board,visted,word,depth+1);
            visted[i-1][j] = false;
            if(flag) return true;
            
        }
        //down
        if(i+1<board.length &&!visted[i+1][j]) {
            flag = flag || dfs(i+1,j,board,visted,word,depth+1);
            visted[i+1][j] = false;
            if(flag) return true; 
        }
        //left
        if(j-1 >=0 && !visted[i][j-1]){
            flag = flag || dfs(i,j-1,board,visted,word,depth+1);
            visted[i][j-1] = false;
            if(flag) return true; 
        }
        //right    
        if(j+1<board[0].length&& !visted[i][j+1]){
           flag = flag ||  dfs(i,j+1,board,visted,word,depth+1);
           visted[i][j+1] = false;
           if(flag) return true; 
        }
        
        return flag;
    }
}

又改成了:

class Solution {
    public boolean exist(char[][] board, String word) {
        
        int row = board[0].length;
        int col = board.length;
        
        
         boolean[][] visted = new boolean[col][row];
        for(int i=0; i<col; i++){
            for(int j=0; j<row; j++){
               // System.out.println("start: "+ i+ " "+ j);
               
                if(dfs(i,j,board,visted,word,0)) return true;
               // visted[i][j] = false;
            }
        }
        return false;
           
    }
    
    private boolean dfs(int i, int j, char[][] board, boolean[][] visted, String word, int depth){

                

        if(board[i][j] != word.charAt(depth)) return false;

        if(depth == word.length()-1){
            return true;
        }
        
        boolean flag = false;
        
        visted[i][j] = true;
        //System.out.println(i+ " "+ j);
        //System.out.println(depth);
      
        
        //up
        if(i-1>=0&& !visted[i-1][j]){
            flag = flag || dfs(i-1,j,board,visted,word,depth+1);
           // visted[i-1][j] = false;
            
            
        }
        //down
        if(i+1<board.length &&!visted[i+1][j]) {
            flag = flag || dfs(i+1,j,board,visted,word,depth+1);
           // visted[i+1][j] = false;
           
        }
        //left
        if(j-1 >=0 && !visted[i][j-1]){
            flag = flag || dfs(i,j-1,board,visted,word,depth+1);
          //  visted[i][j-1] = false;
           
        }
        //right    
        if(j+1<board[0].length&& !visted[i][j+1]){
           flag = flag ||  dfs(i,j+1,board,visted,word,depth+1);
          // visted[i][j+1] = false;
          
        }
        visted[i][j] = false;
        return flag;
    }
}

之所以写的不好,主要因为,应该把 边界条件和是否已经被访问 判断放在 下一次函数调用里,而不是本次里, 修改后的程序简单很多。

back traking 体现在 visted[i][j] = true ; dfs(...) ; visted[i][j] = false;

class Solution {
    public boolean exist(char[][] board, String word) {
        
        int row = board[0].length;
        int col = board.length;
        
        
         boolean[][] visted = new boolean[col][row];
        for(int i=0; i<col; i++){
            for(int j=0; j<row; j++){    
                if(dfs(i,j,board,visted,word,0)) return true;
               
            }
        }
        return false;
           
    }
    
    private boolean dfs(int i, int j, char[][] board, boolean[][] visted, String word, int depth){

                
        if(i<0 || j<0 || i >=board.length || j>=board[0].length ) return false; 
        
        if(board[i][j] != word.charAt(depth)) return false;
        
        if(visted[i][j]) return false;

        if(depth == word.length()-1){
            return true;
        }
        
        
        
         visted[i][j] = true;
         boolean flag =   dfs(i-1,j,board,visted,word,depth+1) ||dfs(i+1,j,board,visted,word,depth+1) 
                       || dfs(i,j-1,board,visted,word,depth+1)|| dfs(i,j+1,board,visted,word,depth+1);
 
         visted[i][j] = false;
         return flag;
    }
}
212. Word Search II
和79 基本雷同,给你 一个 string[] words, 要你找出 words 符合 79题搜索条件的单词。
如果用 dfs, 在 79题基础上加个for 循环就好了。
但有个坑爹的地方: 字典: ["a"] words = ["a","a"] ,只能回 "a" ,而不能回 "a","a" 因此需要用set 存放结果。

更好的做法是用tier tree, 待续。

猜你喜欢

转载自www.cnblogs.com/keepAC/p/9972760.html