题目描述[原题链接][https://leetcode-cn.com/problems/sudoku-solver/]
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。![]()
一个数独。![]()
答案被标成红色。
Note:
给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9 x 9 形式的。
算法描述
使用的概念
了解两个编程概念会对接下来的分析有帮助。
第一个叫做 约束编程。
基本的意思是在放置每个数字时都设置约束。在数独上放置一个数字后立即
排除当前 行, 列 和 子方块 对该数字的使用。这会传播 约束条件 并有利于减少需要考虑组合的个数。

第二个叫做 回溯。
让我们想象一下已经成功放置了几个数字
在数独上。
但是该组合不是最优的并且不能继续放置数字了。该怎么办? 回溯。
意思是回退,来改变之前放置的数字并且继续尝试。如果还是不行,再次 回溯。

如何枚举子方块
一种枚举子方块的提示是:
使用 方块索引= (行 / 3) * 3 + 列 / 3
其中 / 表示整数除法。

算法
现在准备好写回溯函数了backtrack(row = 0, col = 0)。
从最左上角的方格开始
row = 0, col = 0。直到到达一个空方格。从
1到9迭代循环数组,尝试放置数字d进入(row, col)的格子。如果数字
d还没有出现在当前行,列和子方块中:将
d放入(row, col)格子中。记录下
d已经出现在当前行,列和子方块中。如果这是最后一个格子
row == 8, col == 8:- 意味着已经找出了数独的解。
否则
- 放置接下来的数字。
如果数独的解还没找到:
将最后的数从
(row, col)移除。
C++代码
1 | class Solution { |
Java代码
1 | class Solution { |