Sudoku Solver
Solution 1
基于前一道题的拓展,本题实际上是dfs的教科书题,和N皇后问题的思路是一致的:在当前配置方案有效的情况下枚举下一种情况。整个枚举过程使用dfs实现,但是判断有效不能直接用上一个题的实现(似乎是因为我的实现申请内存操作过于频繁TLE了),而是采用了[LeetCode] 37. Sudoku Solver 求解数独 - Grandyang - 博客园 (cnblogs.com)这里面的解法,只针对当前位置判定有效就可以了。(原是我的思路不够好/(ㄒoㄒ)/~~)
- 这个题看起来很复杂,但是由于数独的空位个数是有上限的,所以本题仍然是常数的时间复杂度,同时空间复杂度也是常数级别。
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
this->dfs(board, 0, 0);
}
private:
bool dfs(vector<vector<char>>& board, int posX, int posY) {
// 搜索顺序:行优先
if (posX >= 9) {
return true; // 全部枚举完毕,填满可解
}
else if (posY >= 9) {
return this->dfs(board, posX + 1, 0); // 当前行填满,开始向下一行枚举
}
else if (board[posX][posY] != '.') {
return this->dfs(board, posX, posY + 1); // 非空位,跳过
}
else {
// 有效位,开始枚举
for (char c = '1'; c <= '9'; ++c) {
if (this->isValidSudoku(board, posX, posY, c)) {
board[posX][posY] = c;
if (this->dfs(board, posX, posY + 1)) {
return true;
}
board[posX][posY] = '.';
}
}
}
return false;
}
bool isValidSudoku(vector<vector<char>>& board, int posX, int posY, char c) {
for (int i = 0; i < 9; ++i) {
if (board[i][posY] == c) {
return false;
}
}
for (int j = 0; j < 9; ++j) {
if (board[posX][j] == c) {
return false;
}
}
int row = posX - posX % 3, col = posY - posY % 3;
for (int offsetX = 0; offsetX < 3; ++offsetX) {
for (int offsetY = 0; offsetY < 3; ++offsetY) {
if (board[row + offsetX][col + offsetY] == c) {
return false;
}
}
}
return true;
}
};
Solution 2
官方题解解数独 - 解数独 - 力扣(LeetCode) (leetcode-cn.com)使用位状态进一步优化了判定过程(官方题解的前一题使用一个数组保存同行、同列、同块的状态,我的实现是用哈希表),每一个位对应不同的数字(最低位对应0,最高位对应9)是否出现。
Solution 3
Solution 1的python实现
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
self.__dfs(board, 0, 0)
def __dfs(self, board: List[List[str]], posX: int, posY: int) -> bool:
# print(board[0][2])
if posX >= 9: return True
elif posY >= 9: return self.__dfs(board, posX + 1, 0)
elif board[posX][posY] != '.': return self.__dfs(board, posX, posY + 1)
else:
namelist = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
for c in namelist:
# print(str(c))
if self.__isValidSudoku(board, posX, posY, str(c)):
# print('K')
board[posX][posY] = str(c)
if self.__dfs(board, posX, posY + 1): return True
board[posX][posY] = '.'
return False
def __isValidSudoku(self, board: List[List[str]], posX: int, posY: int, c:str) -> bool:
for i in range(9):
if board[i][posY] == c: return False
for j in range(9):
if board[posX][j] == c: return False
row, col = posX - posX % 3, posY - posY % 3
for offsetX in range(3):
for offsetY in range(3):
if board[row + offsetX][col + offsetY] == c: return False
return True
本文介绍了一种基于深度优先搜索(DFS)的数独求解算法,并提供了C++及Python两种语言的实现方式。该算法通过递归地检查每个空格的有效填数,确保行、列及宫内不重复,最终完成数独填充。

被折叠的 条评论
为什么被折叠?



