36. Valid Sudoku/37. Sudoku Solver - 数独问题-- backtracking 经典
Posted keepac
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; } }
以上是关于36. Valid Sudoku/37. Sudoku Solver - 数独问题-- backtracking 经典的主要内容,如果未能解决你的问题,请参考以下文章