leetcode原题
37. 解数独
难度:困难
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。
一个数独。
答案被标成红色。
Note:
给定的数独序列只包含数字 1-9 和字符 ‘.’ 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。
以下是我参照评论区大佬写的
递归回溯算法的C++代码
class Solution
{
public:
void solveSudoku(vector<vector<char>>& board)
{
// 记录某行,某位数字是否已经被摆放
array<array<bool,9>,9> row{};
// 记录某列,某位数字是否已经被摆放
array<array<bool,9>,9> col{};
// 记录某 3x3 宫格内,某位数字是否已经被摆放
array<array<bool,9>,9> block{};
int num = 0;
for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
{
if(board.at(i).at(j) != '.')
{
num = board.at(i).at(j) - '1';
row.at(i).at(num) = true;
col.at(j).at(num) = true;
// blockIndex = i / 3 * 3 + j / 3, 取整
block.at(i /3 * 3 + j / 3).at(num) = true;
}
}
}
dfs(board, row, col, block, 0, 0);
}
bool dfs(vector<vector<char>>& board, array<array<bool,9>,9>& row,
array<array<bool,9>,9>& col, array<array<bool,9>,9>& block, int i, int j)
{
// 寻找空位置
while(board.at(i).at(j) != '.')
{
if(++j >= 9)
{
++i;
j = 0;
}
if(i >= 9)
{
return true;
}
}
for(int num = 0; num < 9; ++num)
{
int blockIndex = i / 3 * 3 + j / 3;
if(!row.at(i).at(num) && !col.at(j).at(num) && !block.at(blockIndex).at(num))
{
// 递归
board.at(i).at(j) = ('1' + num);
row.at(i).at(num) = true;
col.at(j).at(num) = true;
block.at(blockIndex).at(num) = true;
if(dfs(board, row, col, block, i, j))
{
return true;
}
else
{
// 回溯
row.at(i).at(num) = false;
col.at(j).at(num) = false;
block.at(blockIndex).at(num) = false;
board.at(i).at(j) = '.';
}
}
}
return false;
}
};
以下是我整理的递归回溯算法的一般解法思路:
递归回溯算法思路解析:
- 初始化初值条件
- 递归遍历所有可能的解法
- 列出求解完成时的状态(即停止递归的条件)
- 若递归途中发现解不正确(不是最优解)
- 回溯,回到上一步的状态
- 重复以上2-5,直到求出解
原作者代码链接:
https://leetcode-cn.com/problems/sudoku-solver/comments/2360