编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则

  • 数字 1-9 在每一行只能出现一次。
  • 数字 1-9 在每一列只能出现一次。
  • 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
    数独部分空格内已填入了数字,空白格用 '.' 表示。

    示例:
    37.解数独 - 图1
  1. 输入:board = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]
  2. 输出:[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]
  3. 解释:输入的数独如上图所示,唯一有效的解决方案如下所示:
  4. <img src=" https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2021/04/12/250px-sudoku-by-l2g-20050714_solutionsvg.png" style="height:250px; width:250px" />

提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 '.'
  • 题目数据 保证 输入数独仅有一个解

    解法一:回溯

    1. function solveSudoku(board: string[][]): void {
    2. let n = 9
    3. let rows: Array<Set<string>> = new Array(n).fill(false).map(() => new Set())
    4. let cols: Array<Set<string>> = new Array(n).fill(false).map(() => new Set())
    5. let blocks: Array<Set<string>> = new Array(n).fill(false).map(() => new Set())
    6. // 获取当前属于第几个块
    7. const getBlockNum = (x:number, y:number) => Math.floor(x / 3) + Math.floor(y / 3) * 3
    8. for (let i = 0; i < n ; i++) {
    9. for (let j = 0; j < n; j++) {
    10. rows[i].add(board[i][j])
    11. cols[j].add(board[i][j])
    12. blocks[getBlockNum(i,j)].add(board[i][j])
    13. }
    14. }
    15. const recursion = (x: number, y:number): boolean => {
    16. if (x === 9) {
    17. y++
    18. x = 0
    19. if (y === 9) {
    20. return true
    21. }
    22. }
    23. if (board[x][y] !== '.') {
    24. return recursion(x + 1, y)
    25. }
    26. for (let i = 1; i <= 9; i++) {
    27. const tmp = i + ""
    28. if (rows[x].has(tmp) || cols[y].has(tmp) || blocks[getBlockNum(x, y)].has(tmp)) {
    29. continue
    30. }
    31. board[x][y] = tmp
    32. rows[x].add(tmp)
    33. cols[y].add(tmp)
    34. blocks[getBlockNum(x,y)].add(tmp)
    35. if (recursion(x+1, y)) {
    36. return true
    37. }
    38. rows[x].delete(tmp)
    39. cols[y].delete(tmp)
    40. blocks[getBlockNum(x,y)].delete(tmp)
    41. board[x][y] = "."
    42. }
    43. return false
    44. }
    45. recursion(0,0)
    46. return
    47. };