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

37. 解数独

时间:2024-10-15 22:50:42浏览次数:13  
标签: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{                                          ......
  • 题解:P10370 「LAOI-4」Mex Tower (Hard ver.)
    ProblemLink「LAOI-4」MexTower(Hardver.)题意给定一个长度为$n$的序列$a$,求序列的$\operatorname{Mex}$值是否大于等于其他所有长度为$n$的自然数序列的$\operatorname{Mex}$值。Solution不难发现,两个数或一个序列的$\operatorname{Mex}$一定是......
  • ABC375 Review
    ABC375ReviewAB模拟题过C很让人恼怒的一道题,思路一点也不难想,但是代码实现过于困难了(对于我来说)分析自己找一两组样例就会发现这道题实际上实在模拟一个矩阵不断向内旋转\(90°\)的过程,从外到里旋转的次数越来越多,旋转的过程可以发现实际上可以通过模\(4\)来进行简化......