仰望星空的人,不应该被嘲笑
题目描述
编写一个程序,通过填充空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.'
表示。
一个数独。
答案被标成红色。
提示:
给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sudoku-solver
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
我们一行一行的放,如果能得到一个解,直接返回 true
,然后剪枝条件如下述 check
函数。
参考xiao_ben_zhu大佬图解
var solveSudoku = function (board) {
let check = (x, y, val) => {
// 一行或者一列有重复元素,剪掉
for (let i = 0; i < 9; i++) {
if (board[x][i] == val || board[i][y] == val) return true;
}
let xx = Math.floor(x / 3) * 3;
let yy = Math.floor(y / 3) * 3;
// 3x3宫格内重复的情况,剪掉
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (board[xx + i][yy + j] == val) return true;
}
}
return false; // 没有冲突情况
}
let dfs = (x, y) => {
if (y == 9) {
x++;
y = 0;
if (x == 9) return true; // 都填完了,直接返回 true
}
if (board[x][y] != '.') return dfs(x, y + 1);
for (let i = 1; i < 10; i++) {
if (check(x, y, String(i))) continue;
board[x][y] = String(i);
if (dfs(x, y + 1)) return true; // 如果往下走,能够解出数独,直接返回 true
board[x][y] = '.'; // 回溯,因为往下走得不到一个解
}
return false;
}
dfs(0, 0);
return board;
};
最后
文章产出不易,还望各位小伙伴们支持一波!
往期精选:
访问超逸の博客,方便小伙伴阅读玩耍~
学如逆水行舟,不进则退