【LeetCode每日一题】——37.解数独
创始人
2024-02-16 16:53:36
0

文章目录

  • 一【题目类别】
  • 二【题目难度】
  • 三【题目编号】
  • 四【题目描述】
  • 五【题目示例】
  • 六【解题思路】
  • 七【题目提示】
  • 八【时间频度】
  • 九【代码实现】
  • 十【提交结果】

一【题目类别】

  • 数组

二【题目难度】

  • 困难

三【题目编号】

  • 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”]]
    • 解释:输入的数独如上图所示,唯一有效的解决方案如下所示:
    • 在这里插入图片描述

六【解题思路】

  • 此题有难度,但是还是回溯的思想。回溯算法的模板如下:
void backTracking(参数)
{if(终止条件){保存结果;return;}for(遍历从当前位置出发的所有“路径”){保存“路径”节点;backTracking(所需参数);回溯处理,删除上一步保存的“路径”节点,准备进行新的递归}
}
  • 有了以上模板,我们只需要往里面填入解决这道题所需的“工具”,首先有几个定义我们要清楚:
    • row[i][digit]:表示digit这个数字出现在了第i行
    • col[j][digit]:表示digit这个数字出现在了第j列
    • block[i][j][dight]:表示digit这个数字出现在了第i、j块
    • valid:表示是否应该结束递归
    • spaces:存储需要填入数字的位置
  • 首先遍历整个二维数组,当我们遍历到某个位置:
    • 如果此位置是“.”:说明需要填入数字,那么将此位置存入spaces,准备填入数字
    • 如果此位置是数字:那将此行、此列和此块对应这个数字都置为true,也就是不能再出现这个数字了
  • 然后进入递归算法,这里面就简单了,就是上面模板写的过程,只需要判断当前数字是否出现在此行、此列和此块即可
  • 此外还需要注意真正的数字和数组下标之间的关系
  • 其他细节可以参考代码
  • 最后不需要返回值

七【题目提示】

  • board.length==9board.length == 9board.length==9
  • board[i].length==9board[i].length == 9board[i].length==9
  • board[i][j]是一位数字或者′.′board[i][j] 是一位数字或者 '.'board[i][j]是一位数字或者′.′
  • 题目数据保证输入数独仅有一个解题目数据 保证 输入数独仅有一个解题目数据保证输入数独仅有一个解

八【时间频度】

  • 时间复杂度:O(n)O(n)O(n),其中nnn为输入数组的行数/列数
  • 空间复杂度:O(1)O(1)O(1)

九【代码实现】

  1. Java语言版
package Array;import java.util.ArrayList;
import java.util.List;/*** @Author: IronmanJay* @Description: 37.解数独* @CreateTime: 2022-11-26  09:36*/
public class p37_SudokuSolver {public static void main(String[] args) {char[][] 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'}};solveSudoku(board);}private static boolean[][] row = new boolean[9][9];private static boolean[][] col = new boolean[9][9];private static boolean[][][] block = new boolean[3][3][9];private static boolean valid = false;private static List spaces = new ArrayList();public static void solveSudoku(char[][] board) {for (int i = 0; i < 9; i++) {for (int j = 0; j < 9; j++) {if (board[i][j] == '.') {spaces.add(new int[]{i, j});} else {int digit = board[i][j] - '0' - 1;row[i][digit] = true;col[j][digit] = true;block[i / 3][j / 3][digit] = true;}}}dfs_back_p37_SudokuSolver(board, 0);}public static void dfs_back_p37_SudokuSolver(char[][] board, int pos) {if (pos == spaces.size()) {valid = true;return;}int[] space = spaces.get(pos);int i = space[0];int j = space[1];for (int digit = 0; digit < 9 && !valid; digit++) {if (!row[i][digit] && !col[j][digit] && !block[i / 3][j / 3][digit]) {row[i][digit] = true;col[j][digit] = true;block[i / 3][j / 3][digit] = true;board[i][j] = (char) (digit + '0' + 1);dfs_back_p37_SudokuSolver(board, pos + 1);row[i][digit] = false;col[j][digit] = false;block[i / 3][j / 3][digit] = false;}}}}
  1. C语言版
#include
#include
#includebool row[9][9];
bool col[9][9];
bool block[3][3][9];
bool valid;
int* spaces[81];
int spaceSize;void dfs_back_p37_SudokuSolver(char** board, int pos)
{if (pos == spaceSize){valid = true;return;}int i = spaces[pos][0];int j = spaces[pos][1];for (int digit = 0; digit < 9 && !valid; digit++){if (!row[i][digit] && !col[j][digit] && !block[i / 3][j / 3][digit]){row[i][digit] = true;col[j][digit] = true;block[i / 3][j / 3][digit] = true;board[i][j] = digit + '0' + 1;dfs_back_p37_SudokuSolver(board, pos + 1);row[i][digit] = false;col[j][digit] = false;block[i / 3][j / 3][digit] = false;}}
}void solveSudoku(char** board, int boardSize, int* boardColSize)
{memset(row, false, sizeof(row));memset(col, false, sizeof(col));memset(block, false, sizeof(block));valid = false;spaceSize = 0;for (int i = 0; i < 9; i++){for (int j = 0; j < 9; j++){if (board[i][j] == '.'){spaces[spaceSize] = malloc(sizeof(int) * 2);spaces[spaceSize][0] = i;spaces[spaceSize++][1] = j;}else{int digit = board[i][j] - '0' - 1;row[i][digit] = true;col[j][digit] = true;block[i / 3][j / 3][digit] = true;}}}dfs_back_p37_SudokuSolver(board, 0);
}/*主函数省略*/

十【提交结果】

  1. Java语言版
    在这里插入图片描述

  2. C语言版
    在这里插入图片描述

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...