解数独
问题描述
- leetcode36 判断数独是否有效的升级版,给定一个未被完成的数独,要求完成。同样包含 3 个要求。
-
数字
1-9
在每一行只能出现一次 -
数字
1-9
在每一列只能出现一次数字1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。
解题思路
- 首先将每行每列、3X3宫内已经出现的元素保存起来;
- 从位置 [0][0] 开始深度搜索。
Java 解法
1 public class Solution { 2 // 利用数组判断数字是否重复,true 代表重复 3 // row[7][1] 代表第 7+1 = 8 行 的字符 1 + 1 = 2 已经使用过了 4 boolean[][] row = new boolean[9][9]; 5 // col[7][2] = true 代表第 7 + 1 = 8 列的字符 2 + 1 = 3 已经使用过了 6 boolean[][] col = new boolean[9][9]; 7 boolean[][][] cell = new boolean[3][3][9]; 8 9 public void solveSudoku(char[][] board) { 10 for (int i = 0; i < 9; i ++) { 11 for (int j = 0; j < 9; j ++) { 12 char c = board[i][j]; 13 if (c != '.') { 14 int k = c - '1'; 15 row[i][k] = true; 16 col[j][k] = true; 17 cell[i/3][j/3][k] = true; 18 } 19 } 20 } 21 22 dfs(board, 0, 0); 23 } 24 25 /** 26 * 27 * @param board 棋盘 28 * @param i 当前行 29 * @param j 当前列 30 * @return 是否可以继续填充 31 */ 32 private boolean dfs(char[][] board, int i, int j) { 33 if (j == 9) { 34 i ++; 35 j = 0; 36 } 37 if (i == 9) return true; 38 39 if (board[i][j] != '.') return dfs(board, i, j + 1); 40 41 for (int k = 0; k < 9; k ++) { 42 if (!row[i][k] && !col[j][k] && !cell[i/3][j/3][k]) { 43 board[i][j] = (char)('1' + k); 44 45 row[i][k] = true; 46 col[j][k] = true; 47 cell[i/3][j/3][k] = true; 48 49 if (dfs(board, i, j + 1)) { 50 return true; 51 } 52 // 回溯后恢复现场 53 row[i][k] = false; 54 col[j][k] = false; 55 cell[i/3][j/3][k] = false; 56 board[i][j] = '.'; 57 } 58 } 59 return false; 60 } 61 }