解数独

204 阅读2分钟
  1. 创建三个存储空间标记位,行,列,九宫格,用于记录哪些数字已经使用了。创建一个空位数组,记录有哪些空位。
  2. 遍历出所有空格,
  3. 如果不是空格,记录标记位为已使用
  4. 深度优先遍历,遍历空格,用每一个空格映射出坐标
    1. 如果所有空格都已经占位,则结束,数独破解成功
    2. 遍历枚举破解 0-9,如果行,列,九宫都没出现过当前数字 i,插入当前数字 i,设置标记位。继续则递归遍历 i + 1,直到所有位置都填完,返回成功。如果没有返回,说明本次数字错误,回撤空间标记位。

输入:

const board = [[".",".","9","7","4","8",".",".","."],
["7",".",".",".",".",".",".",".","."],[".","2",".","1",".","9",".",".","."],
[".",".","7",".",".",".","2","4","."],[".","6","4",".","1",".","5","9","."],
[".","9","8",".",".",".","3",".","."],[".",".",".","8",".","3",".","2","."],
[".",".",".",".",".",".",".",".","6"],[".",".",".","2","7","5","9",".","."]]
/**
 * @param {character[][]} board
 * @return {void} Do not return anything, modify board in-place instead.
 */
var solveSudoku = function(board) {
  let row, column, block, space;
  row = {};
  column = {};
  block = {};
  space = [];
  let temp = [false, false, false, false, false, false, false, false, false];
  let isValid = false;

  var dfs = function (board, pos) {
    if (pos === space.length) {
      isValid = true;
      return;
    }

    let x = space[pos][0];
    let y = space[pos][1];
    for (let i = 0; i < 9 && !isValid; i++) {
      let digit = i + 1;
      if (!row[x][i] && !column[y][i] && !block[Math.floor(x / 3)][Math.floor(y / 3)][i]) {
        row[x][i] = column[y][i] = block[Math.floor(x / 3)][Math.floor(y / 3)][i] = true;
        board[x][y] = digit + '';
        dfs(board, pos + 1);
        row[x][i] = column[y][i] = block[Math.floor(x / 3)][Math.floor(y / 3)][i] = false;
      }
    }
  }

  for (let i = 0; i < 9; i++) {
    row[i] = temp.concat([]);
    column[i] = temp.concat([]);
    let idx = Math.floor(i / 3);
    block[idx] = {'0': temp.concat([]), '1': temp.concat([]), '2': temp.concat([])};
  }

  for (let i = 0; i < 9; i++) {
    for (let j = 0; j < 9; j++) {
      if (board[i][j] === '.') {
        space.push([i, j]);
      } else {
        let digit = parseInt(board[i][j]) - 1;
        row[i][digit] = column[j][digit] = block[Math.floor(i / 3)][Math.floor(j / 3)][digit] = true;
      }
    }
  }

  dfs(board, 0);
};

输出:

[["5","1","9","7","4","8","6","3","2"],["7","8","3","6","5","2","4","1","9"],
["4","2","6","1","3","9","8","7","5"],["3","5","7","9","8","6","2","4","1"],
["2","6","4","3","1","7","5","9","8"],["1","9","8","5","2","4","3","6","7"],
["9","7","5","8","6","3","1","2","4"],["8","3","2","4","9","1","7","5","6"],
["6","4","1","2","7","5","9","8","3"]]