leetcode第37题解数独

109 阅读1分钟

题目: 编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则:

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

我的JavaScript解法

/**
 * @param {character[][]} board
 * @return {void} Do not return anything, modify board in-place instead.
 */

var solveSudoku = function(board) {
  track(board, 0, 0)
};

var track = (board, rowIndex, colIndex) => {
  if (colIndex == board.length) {
    return track(board, rowIndex+1, 0);
  }
  if (rowIndex == board.length) {
    return true;
  }
  if (board[rowIndex][colIndex] != '.') {
    return track(board, rowIndex, colIndex+1);
  }
  for(let val = 1; val <= 9; val++) {
    if (!isValid(rowIndex, colIndex, `${val}`, board))
      continue;
    
    board[rowIndex][colIndex] = `${val}`;
    if (track(board, rowIndex, colIndex+1)) {
      return true;
    }
    board[rowIndex][colIndex] = '.';
  }
  return false;
}

function isValid(row, col, val, board) {
  // 行中列中的数字不能重复
  if (board[row].includes(val) || board.map((item) => item[col]).includes(val)) return false;
  let startRow = Math.floor(row / 3) * 3
  let startCol = Math.floor(col / 3) * 3

  //方块中的数字不能重复
  for(let i = startRow; i < startRow + 3; i++) {
    if (board[i].slice(startCol, startCol + 3).includes(val))
      return false;
  }

  return true
}

解析: 利用回溯法暴力搜索

循环行和列,尝试在每个位置放置1-9,并检验合法性,包括行、列、3 * 3方块的合法性,如果合法继续循环,直到找到一个合法的解,如果不合法,则回溯状态,并继续尝试其他的可能性

  • 时间复杂度:O(n2)O(n^2)(待定)