原创 提交时才注意到要 in-place 所以后来打了两层循环给 board 一个个赋值
/**
* @param {character[][]} board
* @return {void} Do not return anything, modify board in-place instead.
*/
var solveSudoku = function(board) {
function check(val, i, j, result) {
for (let k = 0; k < 9; ++k) {
// 横向检查
if (result[i][k] === val) return false;
// 纵向清理
if (result[k][j] === val) return false;
}
// 小九宫格校验
const startX = Math.floor(i / 3) * 3;
const startY = Math.floor(j / 3) * 3;
for (let p = startX; p < startX + 3; ++p) {
for (let q = startY; q < startY + 3; ++q) {
if (p === i || q === j) continue;
const tmp = result[p][q];
if (tmp === val) return false;
}
}
return true;
}
function dig(r, data, pointer = 0) {
const result = r.map((arr) => arr.slice());
const {
posses,
i,
j,
} = data[pointer];
if (r[i][j] !== '.') {
dig(result, data, pointer + 1);
return;
}
for (let t = 0; t < posses.length; ++t) {
const v = posses[t];
if (check(v, i, j, result)) { // 初步检测通过
result[i][j] = v;
if (pointer === data.length - 1) { // 这波假设成功了
for (let ii = 0; ii < 9; ++ii) {
for (let jj = 0; jj < 9; ++jj) {
board[ii][jj] = result[ii][jj];
}
}
throw new Error();
return;
}
dig(result, data, pointer + 1);
}
}
}
const data = [];
// 第一波循环,预处理好可选项
for (let i = 0; i < 9; ++i) {
for (let j = 0; j < 9; ++j) {
const char = board[i][j];
let posses = '123456789';
if (char === '.') { // 未确定
for (let k = 0; k < 9; ++k) {
// 横向清理
const tmp = board[i][k];
if (tmp !== '.') {
posses = posses.replace(tmp, '');
}
// 纵向清理
const tmp2 = board[k][j];
if (tmp2 !== '.') {
posses = posses.replace(tmp2, '');
}
}
// 小九格清理
const startX = Math.floor(i / 3) * 3;
const startY = Math.floor(j / 3) * 3;
for (let p = startX; p < startX + 3; ++p) {
for (let q = startY; q < startY + 3; ++q) {
if (p === i || q === j) continue;
const tmp = board[p][q];
if (tmp !== '.') {
posses = posses.replace(tmp, '');
}
}
}
if (posses.length !== 1) {
data.push({
char,
posses,
i,
j,
});
} else {
board[i][j] = posses[0];
}
}
}
}
try {
dig(board, data);
} catch (e) {
return;
}
};