掘金团队号上线,助你 Offer 临门! 点击 查看大厂春招职位
一、题目描述:
编写一个程序,通过填充空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 空白格用 '.' 表示。
提示:
- 给定的数独序列只包含数字 1-9 和字符 '.' 。
- 你可以假设给定的数独只有唯一解。
- 给定数独永远是 9x9 形式的。
题目地址:leetcode-cn.com/problems/su…
二、思路分析:
由于提示数独只有一个唯一解,所以不用考虑无解和多解的情况,所以解法就与排列数类似了。记录每一行,每一列,每一个小九宫格中出现的数字情况,然后进行深度优先搜索。
使用3个二维数组,分别记录 每一行、每一列、每个小九宫格里已经出现的数字。下标代表数字,值代表是否出现过然后使用 DSF。对每个需要填充的单元格进行递归。递归时根据之前统计的3个二维数组来判断应该填哪个数字
三、AC 代码:
public static boolean filling(char[][] board, int[][] row, int[][] col, int[][] square) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == '.') {
for (int k = 0; k < 9; k++) {
int sIndex = i / 3 * 3 + j / 3;
if (row[i][k] == 0 && col[j][k] == 0 && square[sIndex][k] == 0) {
board[i][j] = ((k + 1) + "").charAt(0);
row[i][k] = col[j][k] = square[sIndex][k] = 1;
if (filling(board, row, col, square)) {
return true;
} else {
board[i][j] = '.';
row[i][k] = col[j][k] = square[sIndex][k] = 0;
}
}
}
return false;
}
}
}
return true;
}
public static void solveSudoku(char[][] board) {
int[][] row = new int[9][9];
int[][] col = new int[9][9];
int[][] square = new int[9][9];
//init array
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
int num = board[i][j] - '0' - 1;
//根据 i、j 计算属于第几个九宫格
int sIndex = i / 3 * 3 + j / 3;
row[i][num] = col[j][num] = square[sIndex][num] = 1;
}
}
}
filling(board, row, col, square);
}
四、总结:
很笨的一种方法,但是比较容易理解,LeetCode 上有一种利用位运算解法。但是不太容易想明白。