LeetCode0037-解数独
题目:
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。
一个数独
答案被标成红色
Note:
- 给定的数独序列只包含数字 1-9 和字符 ‘.’ 。
- 你可以假设给定的数独只有唯一解。
- 给定数独永远是 9x9 形式的。
分析:
约束编程
基本的思想是在放置每个数字时都设置约束,在数独上放置一个数字后立即排除当前行,列和小九宫格对该数字的使用。这会传播约束条件并有利于减少需要考组合的个数。
回溯
想象一下已经成功放置了几个数字在数独上,但是该组合不是最优的并且不能继续放置数字了,怎么办?回溯。
意思就是回退,来改变之前放置的数字并继续尝试,如果还是不行,再次 回溯。
如果枚举小九宫格
使用小九宫格的索引 = (行 / 3)* 3 + 列 / 3
其中 / 是整除。
代码:
/**
* 0037-解数独
* 编写一个程序,通过已填充的空格来解决数独问题
* 一个数独的解法需要遵循如下规则:
* 数字1-9在每一行只能出现一次
* 数字1-9在每一列只能出现一次
* 数字1-9在每个3*3的九宫格中只能出现一次
*/
class Solution {
public void solveSudoku(char[][] board) {
backtrack(board, 0, 0);
}
/**
* 回溯函数
*
* @param board 数独存储字符数组
* @param i 当前状态的行标
* @param j 当前状态的列标
* @return
*/
private boolean backtrack(char[][] board, int i, int j) {
// 定义并初始化行列索引最大值
int rows = 9, columns = 9;
if (j == columns) {
// 穷举到最后一列的话就换到下一行重新开始
return backtrack(board, i + 1, 0);
}
if (i == rows) {
// 找到一个可行解,直接结束
return true;
}
if (board[