1 问题
编写一个程序,通过填充空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。
一个数独。
答案被标成红色。
提示:
给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。
2 解法
一个for循环遍历棋盘的行,一个for循环遍历棋盘的列,一行一列确定下来之后,递归遍历这个位置放9个数字的可能性。
class Solution {
public:
bool backtracking(vector<vector<char>>& board)
{
//遍历棋盘行
for(int i = 0; i < board.size(); i++)
{
//遍历棋盘列
for(int j = 0; j < board[0].size(); j++)
{
//board[i][j]位置不为空,则开始下次循环
if(board[i][j] != '.')
continue;
for(char k = '1'; k <= '9'; k++)
{
//判断在i、j位置是否能够放入k
if(isValid(i, j, k, board))
{
board[i][j] = k;
//递归
if(backtracking(board)) // 如果找到合适一组立刻返回
return true;
//回溯
board[i][j] = '.';
}
}
//1~9都不能放入board[i][j]位置
return false;
}
}
return true; // 遍历完没有返回false,说明找到了合适棋盘位置了
}
bool isValid(int row, int col, char k, vector<vector<char>>& board)
{
//1. 1-9每行只能出现一次,遍历0-row-1,看是否出现k
for(int i = 0; i < 9; i++)
{
if(board[row][i] == k)
return false;
}
//2. 1-9每列只能出现一次,遍历0-col-1,看是否出现k
for(int i = 0; i < 9; i++)
{
if(board[i][col] == k)
return false;
}
//3. 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次
//找到 3x3 宫格的左上角顶点位置
int startX = (row / 3) * 3;
int startY = (col / 3) * 3;
for(int i = startX; i < startX + 3; i++)
{
for(int j = startY; j < startY + 3; j++)
{
if(board[i][j] == k)
return false;
}
}
return true;
}
void solveSudoku(vector<vector<char>>& board) {
backtracking(board);
}
};