2024-09-01
算法刷题
00

难度可以控制,且解法唯一,时间复杂度看运气。

首先,我们定义了一个 SudokuGenerator 类。然后,我们定义了 generate 方法来生成数独游戏。该方法生成了一个 9 × 9 的矩阵,初始值为 '.'。接着,使用 solveSudoku 方法来解决数独游戏,并将解决后的结果存放在生成的矩阵中。

在求解数独游戏时,我们使用深度优先搜索算法来实现。对于每个单元格,首先检查它是否有预设值(即是否为 '.'),如果有,直接跳过。如果没有,我们随机生成1~9的数字,并检查该数字是否符合数独规则,如果不符合规则,就换一个数字再次尝试,直到找到符合规则的数字。将符合规则的数字填入该单元格,并继续向后搜索,直到搜索完成整个数独游戏。

然后,我们定义了 removeNumbers 方法来删除数独游戏,使难度符合所选根据。在此方法中,我们使用深度优先搜索算法来逐步删除数独游戏中的数字。我们找到所有预设数字的单元格,并随机打乱它们的顺序。然后尝试删除单元格中的数字,并确保解法唯一,如果解法唯一,继续删除数字,否则回退上一个状态。

最后,我们定义了 isUnique 和 solve 方法来解决数独游戏。isUnique 方法用于确定给定的游戏是否具有唯一解。该方法使用深度优先搜索算法,在填写数字的过程中判断是否出现多个解决方案。 solve 方法解决数独游戏,将字符串表示为数独板,并返回解决结果的一个布尔值。

python
import random class SudokuGenerator: def __init__(self, difficulty): # 限制在30和60之间 if difficulty < 30: self.difficulty = 30 elif difficulty > 60: self.difficulty = 60 else: self.difficulty = difficulty def generate(self): board = [['.' for _ in range(9)] for _ in range(9)] self.solveSudoku(board) self.removeNumbers(board, self.difficulty) return board def solveSudoku(self, board): def dfs(board, row, col): if col == 9: return dfs(board, row + 1, 0) if row == 9: return True if board[row][col] != '.': return dfs(board, row, col + 1) nums = list(range(1, 10)) random.shuffle(nums) for i in nums: if not isValid(board, row, col, str(i)): continue board[row][col] = str(i) if dfs(board, row, col + 1): return True board[row][col] = '.' return False def isValid(board, row, col, c): for i in range(9): if board[i][col] == c: return False if board[row][i] == c: return False if board[(row // 3) * 3 + i // 3][(col // 3) * 3 + i % 3] == c: return False return True dfs(board, 0, 0) def removeNumbers(self, board, difficulty): def dfs(board, num): if num == 0: return True lst = [(i, j) for i in range(9) for j in range(9) if board[i][j] != '.'] lst = sorted(lst, key=lambda x: random.random()) for i, j in lst: c = board[i][j] board[i][j] = '.' if not self.isUnique(board): board[i][j] = c elif dfs(board, num - 1): return True else: board[i][j] = c return False dfs(board, difficulty) def isUnique(self, board): s = ''.join([''.join(row) for row in board]) solver = SudokuSolver() return solver.solve(s) class SudokuSolver: def solve(self, s): board = [[s[i * 9 + j] for j in range(9)] for i in range(9)] return self.solveSudoku(board) def solveSudoku(self, board): def dfs(board, row, col): if col == 9: return dfs(board, row + 1, 0) if row == 9: return True if board[row][col] != '.': return dfs(board, row, col + 1) for i in range(1, 10): if not isValid(board, row, col, str(i)): continue board[row][col] = str(i) if dfs(board, row, col + 1): return True board[row][col] = '.' return False def isValid(board, row, col, c): for i in range(9): if board[i][col] == c: return False if board[row][i] == c: return False if board[(row // 3) * 3 + i // 3][(col // 3) * 3 + i % 3] == c: return False return True return dfs(board, 0, 0) generator = SudokuGenerator(50) # 挖空多少个格子 board = generator.generate() for row in board: print(row) print(str(board).count("."))

检查时间复杂度:

python
import time ties = [] for _ in range(100): t0 = time.time() generator = SudokuGenerator(60) # 挖空多少个格子 board = generator.generate() # for row in board: # print(row) ties.append(time.time() - t0) print(max(ties)) print(min(ties)) print(sum(ties) / len(ties))

得到的生成游戏所消耗的时间是:

254.41049194335938

0.02700185775756836

7.814508402347565

最大时间居然需要254秒,需要改进。

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!