LeetCode题练习与总结:解数独

2024-03-17 10:04
文章标签 leetcode 总结 练习 解数

本文主要是介绍LeetCode题练习与总结:解数独,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、题目

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 '.' 表示。

二、解题思路

  1. 选择一个空格:在数独板上找一个还没有填数字的空格。
  2. 尝试填入数字:尝试在该空格中填入1到9之间的数字。
  3. 检查有效性:检查填入的数字是否满足数独的规则。这包括检查当前行、列和3x3的子宫格。
  4. 递归解决:如果填入的数字有效,递归地尝试解决剩余的空格。
  5. 回溯:如果在递归过程中发现当前填入的数字导致无法继续填入其他空格,回溯到上一个空格,尝试填入另一个数字。

三、具体代码

class Solution {public void solveSudoku(char[][] board) {if (board == null || board.length != 9 || board[0].length != 9) {return;}solve(board, 0, 0); // 从第一个空格开始递归解决}private boolean solve(char[][] board, int row, int col) {if (row == 9) { // 如果到达最后一行,意味着所有空格都已尝试,返回成功return true;}if (col == 9) { // 移动到下一行return solve(board, row + 1, 0);}if (board[row][col] != '.') { // 如果当前格有数字,移动到下一列return solve(board, row, col + 1);}// 尝试填入1到9之间的数字for (char num = '1'; num <= '9'; num++) {if (isValid(board, row, col, num)) {board[row][col] = num; // 填入数字if (solve(board, row, col + 1)) { // 递归解决下一个空格return true;}board[row][col] = '.'; // 回溯,移除数字}}return false; // 如果没有数字可以填入,返回失败}private boolean isValid(char[][] board, int row, int col, char num) {// 检查行for (int i = 0; i < 9; i++) {if (board[row][i] == num) {return false;}}// 检查列for (int i = 0; i < 9; i++) {if (board[i][col] == num) {return false;}}// 检查3x3子宫格int startRow = row - row % 3;int startCol = col - col % 3;for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if (board[startRow + i][startCol + j] == num) {return false;}}}return true; // 如果数字不违反规则,返回true}
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 时间复杂度主要取决于尝试填充数字的次数以及每次尝试时的验证过程。
  • 尝试次数:最坏情况下,每个空格都尝试填入1到9之间的所有数字,因此尝试次数大约是 9^9(因为9x9的数独有81个空格,每个空格最多尝试9次)。
  • 验证过程:每次尝试填入数字时,都需要验证该数字是否有效,这包括检查当前行、列和3x3的宫。最坏情况下,每个验证过程需要检查9个元素,因此对于每次尝试,验证过程的时间复杂度是 O(9)
  • 综上所述,最坏情况下的时间复杂度是 O(9^9 * 9),即 O(9^10)
  • 这是一个非常巨大的数字,但在实际情况中,由于数独的规则限制,通常不需要尝试所有可能的数字组合。
2. 空间复杂度
  • 空间复杂度主要取决于递归调用栈的深度。
  • 递归调用栈:在最坏情况下,每次递归调用都可能需要进入一个新的递归层级,直到找到一个合适的数字或者填满所有空格。由于数独最多有81个空格,递归调用栈的最大深度为81。
  • 因此,空间复杂度是 O(递归调用栈深度),即 O(81)O(1),因为这里的常数可以忽略不计。

五、总结知识点

  1. 回溯算法:这是一种通过递归来实现的深度优先搜索策略。它尝试在给定的问题空间中搜索解决方案,并且在搜索过程中,如果遇到不可行的路径,会返回到上一步,尝试其他可能的选项。

  2. 递归solve 方法是一个递归函数,它尝试填入数字并递归地调用自身来解决剩余的空格。递归的基本情况是当所有空格都被填满时,这时会返回 true,表示找到了一个解决方案。

  3. 参数传递solve 方法通过 boardrowcol 三个参数来跟踪当前的数独板状态和下一个需要填充的空格位置。

  4. 边界检查:在 solve 方法的开始,有对 rowcol 的边界检查,确保它们不会超出数独板的范围。

  5. 条件判断:代码中有多个条件判断,用于确定当前位置是否可以填入某个数字。这包括检查当前行、列和3x3的宫格内是否已经存在该数字。

  6. 有效性验证isValid 方法用于验证尝试填入的数字是否符合数独的规则。它检查了三个维度:行、列和3x3的宫格。

  7. 回溯:当尝试填入的数字导致冲突时,通过将当前位置的值重置为 '.'(表示空格),算法会回溯到上一步,尝试其他可能的数字。

  8. 字符操作:代码中使用了字符型变量 num 来表示数字1到9,这是为了与数独板上的字符表示保持一致。

  9. 数学计算:在计算3x3宫格的起始行和列时,使用了取模运算 % 来确定当前位置所在的宫格。

  10. 空格处理:代码中对数独板上的空格('.')进行了特殊处理,只有当当前位置是空格时,才会尝试填入数字。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

这篇关于LeetCode题练习与总结:解数独的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/818632

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;

RabbitMQ练习(AMQP 0-9-1 Overview)

1、What is AMQP 0-9-1 AMQP 0-9-1(高级消息队列协议)是一种网络协议,它允许遵从该协议的客户端(Publisher或者Consumer)应用程序与遵从该协议的消息中间件代理(Broker,如RabbitMQ)进行通信。 AMQP 0-9-1模型的核心概念包括消息发布者(producers/publisher)、消息(messages)、交换机(exchanges)、

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists