赞
踩
题目链接:37. 解数独
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
1-9
在每一行只能出现一次。1-9
在每一列只能出现一次。1-9
在每一个以粗实线分隔的 3x3
宫内只能出现一次。(请参考示例图)数独部分空格内已填入了数字,空白格用 '.'
表示。
示例 1:
输入:board = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]] 输出:[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]] 解释:输入的数独如上图所示,唯一有效的解决方案如下所示:
提示:
board.length == 9
board[i].length == 9
board[i][j]
是一位数字或者 '.'
文章讲解:代码随想录
视频讲解:回溯算法二维递归?解数独不过如此!| LeetCode:37. 解数独_哔哩哔哩_bilibili
思路:使用回溯法求解棋盘类问题。
回溯分析:
- /**
- * @param {character[][]} board
- * @return {void} Do not return anything, modify board in-place instead.
- */
- var solveSudoku = function(board) {
- const rowState = new Array(9).fill().map(() => new Array(9).fill(false)); // 行状态
- const colState = new Array(9).fill().map(() => new Array(9).fill(false)); // 列状态
- const squierState = new Array(3).fill().map(() => new Array(3).fill().map(() => new Array(9).fill(false))); // 单元状态
- // 初始化状态表
- for (let i = 0; i < 9; i++) {
- for (let j = 0; j < 9; j++) {
- if (board[i][j] === ".") {
- continue;
- }
- rowState[i][board[i][j]] = true;
- colState[j][board[i][j]] = true;
- squierState[parseInt(i / 3)][parseInt(j / 3)][board[i][j]] = true;
- }
- }
- const backtracking = function (num) {
- if (num === 81) {
- return true; // 填充完毕,返回 true
- }
- const col = num % 9; // 计算列数
- const row = (num - col) / 9; // 计算行数
- if (board[row][col] !== ".") {
- return backtracking(num + 1); // 已经有数字了,向下遍历
- }
- // 从1到9尝试填充
- for (let j = 1; j <= 9; j++) {
- // 和规则冲突,尝试填充下一个数
- if (rowState[row][j] || colState[col][j] || squierState[parseInt(row / 3)][parseInt(col / 3)][j]) {
- continue;
- }
- board[row][col] = "" + j; // 填充
- rowState[row][j] = true; // 更新行状态
- colState[col][j] = true; // 更新列状态
- squierState[parseInt(row / 3)][parseInt(col / 3)][j] = true; // 更新单元状态
- // 向下遍历
- if (backtracking(num + 1)) {
- return true; // 已经填充完毕,返还 true
- }
- // 回溯
- board[row][col] = ".";
- rowState[row][j] = false;
- colState[col][j] = false;
- squierState[parseInt(row / 3)][parseInt(col / 3)][j] = false;
- }
- return false;
- }
- backtracking(0);
- };
分析:设 m 为 . 的数量,则时间复杂度为 O(9 ^ m),空间复杂度为 O(n²)。
练习使用回溯法求解棋盘类问题,和 n 皇后问题不同的是,本题需要填充一个二维数组。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。