题目: 编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
- 数字 1-9 在每一行只能出现一次。
- 数字 1-9 在每一列只能出现一次。
- 数字 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方块的合法性,如果合法继续循环,直到找到一个合法的解,如果不合法,则回溯状态,并继续尝试其他的可能性
- 时间复杂度:(待定)