首页 > 其他分享 >37. 解数独

37. 解数独

时间:2024-10-15 22:50:42浏览次数:10  
标签:81 数字 填入 复杂度 37 空格 解数 数独

目录

一、问题描述

二、解题思路

三、代码

四、复杂度分析


一、问题描述

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

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

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

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

二、解题思路

  • 逐格填充:使用回溯算法遍历每一个空格,对于每一个空格,依次尝试填入数字 1 到 9,直到找到一个符合数独规则的数字。
  • 规则检查:对于每一个填入的数字,检查当前数字是否在该行、该列或者该 3x3 宫格中已经存在。
  • 递归回溯:如果某个空格能够被填入一个有效数字,就递归地处理下一个空格。如果某个空格无法填入任何有效数字,就回溯到上一个空格,撤销上一步的选择并尝试其他数字。

三、代码

class Solution {
    public void solveSudoku(char[][] board) {
        solve(board);
    }

    private boolean solve(char[][] board) {
        // 遍历整个数独
        for (int row = 0; row < 9; row++) {
            for (int col = 0; col < 9; col++) {
                // 如果当前是空格(即 '.'),尝试填数字
                if (board[row][col] == '.') {
                    // 尝试填入数字 '1' 到 '9'
                    for (char num = '1'; num <= '9'; num++) {
                        // 检查当前数字是否可以填入
                        if (isValid(board, row, col, num)) {
                            board[row][col] = num;  // 做出选择

                            // 继续填下一个格子
                            if (solve(board)) {
                                return true;  // 如果能成功填完,返回 true
                            }

                            // 如果填入 num 之后无法继续解数独,回溯
                            board[row][col] = '.';  // 撤销选择
                        }
                    }
                    // 如果所有数字都不合适,返回 false,触发回溯
                    return false;
                }
            }
        }
        // 如果所有格子都填完了,返回 true
        return true;
    }

    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 boxRowStart = (row / 3) * 3;
        int boxColStart = (col / 3) * 3;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[boxRowStart + i][boxColStart + j] == num) {
                    return false;
                }
            }
        }

        return true;  // 如果没有冲突,返回 true
    }
}

四、复杂度分析

  • 时间复杂度:最坏情况下的时间复杂度接近 O(981)O(9^{81})O(981)(每个格子都要尝试 9 种数字)。但是由于回溯的剪枝特性,实际运行时间远远小于这个上限。
  • 空间复杂度:由于递归调用的深度最大为 81,空间复杂度为 O(81)=O(1)O(81) = O(1)O(81)=O(1)

标签:81,数字,填入,复杂度,37,空格,解数,数独
From: https://blog.csdn.net/weixin_61695887/article/details/142966257

相关文章

  • 拟声 0.37.0 | 拟物风格,超级优美,功能丰富
    拟声是一款功能丰富的音视频播放器,支持多种音频来源,并具备独特的歌词弹幕、音源转换、跨设备共享与控制等功能。其创新的LRC歌词编解码器和新拟物风格的UI设计为用户提供了一个全新的视听体验。大小:36M百度网盘:https://pan.baidu.com/s/1lNmwmQHtWaOMaf281E-bKA?pwd=olx......
  • Connection to tcp://192.168.112.137:1935?tcp_nodelay=0 failed: Connection timed
    记录一下自己的报错和解决步骤输入catnginx.conf 查看Nginx的配置文件nginx.conf修改nginx核心配置文件nginx,添加rtmp模块rtmp{                                          ......
  • 代码随想录算法训练营第三十一天|455.分发饼干 376. 摆动序列 53. 最大子序和
    455.分发饼干假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干j,都有一个尺寸s[j] 。如果s[j] >=g[i],我们可以将这个饼干j分配给孩子i,......
  • 题解:P9137 [THUPC 2023 初赛] 速战速决
    ProblemLink[THUPC2023初赛]速战速决题目描述题意清晰,不再过多赘述。Solution每张不同的卡是等效的。小\(J\)手上的卡牌只有\(2\)种情况:手上没有相同的牌和有相同的牌。情况\(1\):小\(J\)手上的牌等价于\(1\simn\)(但其实没用),令其手上的牌为\(b_1,b_2,\ldo......
  • 洛谷P1373:小 a 和 uim 之大逃离
    洛谷P1373:小a和uim之大逃离题意略思路DP:记dp[i][j][c][0/1]表示走到\(i\)行\(j\)列时,两人容量之差为\(c\)的方案数,\(0\)表示\(\rm小a\)走的最后一步,\(1\)表示\(\rmuim\)走的最后一步。容易得出转移方程:dp[i][j][l][0]+=dp[i-1][j][l-a[i][j]+k][1];dp[......
  • 题解:P10370 「LAOI-4」Mex Tower (Hard ver.)
    ProblemLink「LAOI-4」MexTower(Hardver.)题意给定一个长度为$n$的序列$a$,求序列的$\operatorname{Mex}$值是否大于等于其他所有长度为$n$的自然数序列的$\operatorname{Mex}$值。Solution不难发现,两个数或一个序列的$\operatorname{Mex}$一定是......
  • 题解:AT_abc370_c [ABC370C] Word Ladder
    题目传送门luogu观看简要题意给两个序列\(S\)和\(T\),输出的第一个数是它能改变的总个数,后面跟着的第\(i\)个是改变\(i\)个数之后,字典序最小的结果。思路当\(S\)与\(T\)相等的话,那就无法改变了,直接输出\(0\)。对于总数只要\(T_i\neS_i\)那它就可以改,所以只......
  • CSP模拟赛 #37
    A题意:给定\(n,a_{1\simn},b_{1\simn}\),两个点\(i,j\)之间有连边当且仅当\(a_i-a_j\lei-j\leb_i-b_j\)或\(a_j-a_i\lej-i\leb_j-b_i\),求图中连通块数量。\(1\len\le10^6\)考虑条件\(a_i-a_j\lei-j\leb_i-b_j\)相当于\(a_i-i\lea_j......
  • ABC375 Review
    ABC375ReviewAB模拟题过C很让人恼怒的一道题,思路一点也不难想,但是代码实现过于困难了(对于我来说)分析自己找一两组样例就会发现这道题实际上实在模拟一个矩阵不断向内旋转\(90°\)的过程,从外到里旋转的次数越来越多,旋转的过程可以发现实际上可以通过模\(4\)来进行简化......
  • SpringBoot&Mybatis的苏果超市商品销售管理系统 毕业设计源码93704
                            摘 要在网络信息的时代,众多的软件被开发出来,给用户带来了很大的选择余地,而且人们越来越追求更个性的需求。在这种时代背景下,超市只能以用户为导向,按品种小批量组织生产,以产品的持续创新作为超市最......