36. Valid Sudoku/37. Sudoku Solver - 数独问题-- backtracking 经典

题意: 经典的递归题,

要求:除了要求 横竖都填满 1~9外, 每个3*3也都要求满足 1~9 

36. 数组可以部分填充, 问是否一个有效的 sudoku. 

写了个好烧脑的 四重循环来check 3*3 的部分。  重点在于 用数组作为hash 。 然后对于 check 3*3 部分, 其实就是9个小方块,  9个小方块 定点坐标为 [0 0] [0 3] [06] [3 0] [3 3 ] [3 6] [6 0] [ 6 3] [6 6] ,每个顶点递增为横竖 递增都 3 , 因此写了个二重循环来控制顶点坐标:

for(int i=0; i<9; i= i+3){
   for(int j=0; j<9; j=j+3) {

  

class Solution {
    public boolean isValidSudoku(char[][] board) {
        
        boolean[][] map_row = new boolean[10][10];
        boolean[][] map_col = new boolean[10][10];       
        //check row and col
        for(int i=0; i<9; i++){
            for(int j=0; j<9; j++){
                if(board[i][j] != '.'){
                    int num = board[i][j] - '0';
                    if(map_row[i][num]) return false;
                    map_row[i][num] = true;
                    if(map_col[num][j]) return false;
                    map_col[num][j] = true;
                }
            }
        }
        
        //check 3*3
        for(int i=0; i<9; i= i+3){
            for(int j=0; j<9; j=j+3) {
                boolean[] map = new boolean[10];
                for(int k=0; k<3; k++){
                    for(int t=0; t<3; t++){
                        int num = board[k+i][t+j] - '0';
                        if(board[k+i][t+j] != '.'){
                            if(map[num]) return false;
                            map[num] = true;
                        }
                    }
                    
                }
            }
        }
     return true;
    }
}

37 终于回到数独问题经典 backtracking 了。 

class Solution {
    public void solveSudoku(char[][] board) {
        
     List<Integer> indexs = new ArrayList<>();   
        
      for(int i=0; i<9; i++)
            for(int j=0; j<9; j++)
                if(board[i][j] == '.')
                    indexs.add(i*9+j);
    
     dfs(board, indexs,0) ;
  }
    
    private boolean dfs(char[][] board, List<Integer> indexs, int depth){
        
        if(depth == indexs.size()) {
            return true;
        }
    
        boolean flag = false;
        int i, j=0;
        int index =  indexs.get(depth);
        i = index/9;
        j = index%9;
        
        for(int n=1; n<=9; n++){
           if(isValid(board, (char)(n+'0'), i, j )  ){
               board[i][j] = (char)(n+'0');
               if (dfs(board,indexs, depth+1)) return true;    //如果满足条件就直接return 了
           } 
        }
        
        // 如果循环结束了,说明 for 循环里 没有成功, 所以 此位置尝试 1~9 均失败,所以 back tracking 回去。
        board[i][j] = '.'; 
        return false;
    }
    
    private boolean isValid(char[][] board, char num, int x,int y){

        int i=0, j=0; 
        for( i=0; i<9; i++){
            if( board[x][i] == num) return false;
        }
        for( j=0; j<9; j++){
            if( board[j][y] == num) return false;
        }
        
        for (i = 3 * (x / 3); i < 3 * (x / 3 + 1); i++)
            for (j = 3 * (y / 3); j < 3 * (y / 3 + 1); j++)
                if (i!=x && j!= y &&board[i][j] == num)
                    return false;
   
        return true;
    }
}

猜你喜欢

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