37. 解数独 - 力扣(LeetCode)

基础知识要求:

Java: 方法、for循环、if else语句、数组

Python: 方法、for循环、if else语句、列表

题目: 

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

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

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 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] 是一位数字或者 '.'
  • 题目数据 保证 输入数独仅有一个解

思路解析:

这个解题思路是一个典型的回溯算法在数独求解问题上的应用,它非常直观且易于理解。下面是对这个解题思路的总结:

  1. 初始化
    • 提供一个初始的数独板(在这个例子中是通过一个二维列表表示的)。
    • 如果数独板没有完全填充(即含有.作为占位符),则需要进行求解。
  2. 定义is_valid函数
    • 这是一个辅助函数,用于检查在给定位置(row, col)填入数字num是否有效。
    • 检查包括:当前行、当前列以及所在的3x3宫格内是否已存在该数字。
  3. 定义solve_sudoku函数
    • 这是求解数独的核心函数,它使用回溯法来尝试填充每一个空格。
    • 对于数独板上的每一个空格(即值为.的位置):
      • 尝试填入数字1到9。
      • 如果填入某个数字后,数独仍然有效(通过is_valid函数检查),则继续递归地求解剩余的空格。
      • 如果递归求解成功(即找到了一个解),则返回True。
      • 如果递归求解失败(即当前数字不合适),则回溯,将该空格重新置为.,并尝试下一个数字。
    • 如果尝试完所有数字后仍然没有找到解,则返回False。
    • 如果所有空格都成功填充,则返回True,表示找到了一个解。
  4. 求解与输出
    • 调用solve_sudoku函数来求解数独。
    • 如果求解成功,则打印出解出的数独板;否则,输出“无解”。

Java代码示例:

public class SudokuSolver {  
  
    // 检查数字在行、列和3x3宫格内是否有效  
    public static 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 = 3 * (row / 3);  
        int startCol = 3 * (col / 3);  
        for (int i = 0; i < 3; i++) {  
            for (int j = 0; j < 3; j++) {  
                if (board[i + startRow][j + startCol] == num) {  
                    return false;  
                }  
            }  
        }  
  
        return true;  
    }  
  
    // 递归求解数独  
    public static boolean solveSudoku(char[][] board) {  
        for (int i = 0; i < 9; i++) {  
            for (int j = 0; j < 9; j++) {  
                if (board[i][j] == '.') {  
                    for (char num = '1'; num <= '9'; num++) {  
                        if (isValid(board, i, j, num)) {  
                            board[i][j] = num;  
  
                            // 递归尝试下一个空格  
                            if (solveSudoku(board)) {  
                                return true;  
                            }  
  
                            // 回溯  
                            board[i][j] = '.';  
                        }  
                    }  
  
                    // 尝试完所有数字都不可行,说明当前空格无解,返回false  
                    return false;  
                }  
            }  
        }  
  
        // 所有空格都填满了,说明找到解了  
        return true;  
    }  
  
    // 主函数,用于测试  
    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'}  
        };  
  
        if (solveSudoku(board)) {  
            // 格式化输出  
            for (char[] row : board) {  
                for (char num : row) {  
                    System.out.print(num + " ");  
                }  
                System.out.println();  
            }  
        } else {  
            System.out.println("无解");  
        }  
    }  
}

Python代码示例:

def is_valid(board, row, col, num):  
    # 检查行中是否已存在该数字  
    for i in range(9):  
        if board[row][i] == num:  
            return False  
    # 检查列中是否已存在该数字  
    for i in range(9):  
        if board[i][col] == num:  
            return False  
    # 检查3x3宫格中是否已存在该数字  
    start_row = 3 * (row // 3)  
    start_col = 3 * (col // 3)  
    for i in range(3):  
        for j in range(3):  
            if board[i + start_row][j + start_col] == num:  
                return False  
    return True
  
def solve_sudoku(board):  
    for i in range(9):  
        for j in range(9):  
            if board[i][j] == '.':  
                for num in ['1', '2', '3', '4', '5', '6', '7', '8', '9']:  
                    if is_valid(board, i, j, num):  
                        board[i][j] = num  
                        if solve_sudoku(board):  
                            return True  
                        # 如果当前数字不合法,回溯  
                        board[i][j] = '.'  
                # 尝试完所有数字都不可行,说明无解  
                return False  
    # 所有空格都填满了,说明找到解了  
    return True  
  
# 示例输入  
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"]]  
  
# 转换为二维列表  
board = [list(map(str, row)) for row in board]  
  
# 求解数独  
if solve_sudoku(board):  
    # 格式化输出  
    for row in board:  
        print(row)  
else:  
    print("无解")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/634209.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu 20/22 安装 Jenkins

1. 使用 apt 命令安装 Java Jenkins 作为一个 Java 应用程序&#xff0c;要求 Java 8 及更高版本&#xff0c;检查系统上是否安装了 Java。 sudo apt install -y openjdk-17-jre-headless安装完成后&#xff0c;再次验证 Java 是否已安装 java --version2. 通过官方存储库安…

Linux多线程系列2: 模拟封装简易语言级线程库,线程互斥和锁,线程同步和条件变量,线程其他知识点

Linux多线程系列2: 模拟封装简易语言级线程库,线程互斥和互斥锁,线程同步和条件变量,线程其他知识点 1.前言 一.模拟C11线程库自己封装简易语言级线程库1.实现框架2.迅速把构造等等函数写完3.start和work1.尝试一2.尝试二3.最终版本4.给出代码 二.模拟实现多线程(为编写线程池做…

Llama 3超级课堂作业笔记

文章目录 基础作业完成 Llama 3 Web Demo 部署环境配置下载模型Web Demo 部署对话截图 使用 XTuner 完成小助手认知微调Web Demo 部署自我认知训练数据集准备训练模型推理验证 使用 LMDeploy 成功部署 Llama 3 模型环境&#xff0c;模型准备LMDeploy CLI chatLMDeploy模型量化(…

php 连接sqlserver步骤

1.首先要确定使用的是sqlserver的哪个版本&#xff0c;比如sqlserver2012 2.确定服务器是64位还是32位的 3.确认一下使用php的哪个版本&#xff0c;比如php7.1 SQL Server 的 Microsoft PHP 驱动程序 Microsoft Drivers for PHP 支持矩阵 - PHP drivers for SQL Server | Mi…

【传知代码】从零开始搭建图像去雾神经网络-论文复现

文章目录 概述原理介绍网络结构 核心逻辑迁移学习子网数据拟合子网 环境配置训练本次复现代码所用数据集测试本次复现代码所用的评价指标 结果展示在O-Haze数据集上的结果在I-Haze数据集上的结果 小结 本文涉及的源码可从从零开始搭建图像去雾神经网络该文章下方附件获取 本文复…

SAP Credit Management-Reconcile Documented Credit Decisions

ECC 升级S4后&#xff0c;经过事后迁移后&#xff0c;出现如下报错 找到了这里的配置路径&#xff1a; DCD settings – to maintain/complete Create Profile for Case Search -> no entry UKM_CASE – DCD search -> no search fields BC set UKM_DCD_CUST not activa…

open drain 与 push pull

Open drain: open drain 输出&#xff1a;输出端相当于三极管的集电极&#xff0c;要得到高电平需要上拉电阻才行。 栅极输入为0时&#xff0c;NMOS 的漏极和源极导通&#xff0c;输出为0。即Uce 0 V。 栅极输入为1时&#xff0c;NMOS不导通&#xff0c;漏极高祖&#xff0…

Element组件 el-select设置滚动条+滚动加载(两种写法: 原生Js和自定义指令)

系列文章目录 提示&#xff1a;下面是简单的功能实现(时间紧迫,大晚上赶工) el-select滚动条相关功能 系列文章目录背景与展望一、使用原生的js实现触底加载1.效果图如下&#xff1a;2.HTML如下3.JS代码如下 二、使用自定义指令解决问题(已补全-2024-05-19)1.效果图如下:2.新增…

如何提交网站到谷歌网站收录?

其实就那么几个步骤&#xff0c;要做谷歌那肯定是需要一个谷歌账号的&#xff0c;然后找到Google Search Console这个谷歌的官方平台&#xff0c;这是最权威的可以统计来自谷歌流量的平台了&#xff0c;毕竟是谷歌自家的&#xff0c;肯定也不可能作假&#xff0c;然后就是跟着平…

使用DockerFile 编写 指令来构建镜像

文章目录 前言使用DockerFile 编写 指令来构建镜像1. 构建2. 验证 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖的话&#x…

二进制部署k8s集群 部署高可用master节点

目录 本次部署的环境 一、master02 节点部署 二、负载均衡部署 安装nginx服务 部署keepalive服务 修改node节点上的配置文件 在master节点上创建pod 三、部署 Dashboard 二进制部署k8s集群部署的步骤总结 &#xff08;1&#xff09;k8s的数据存储中中心的搭建 etcd &…

UNION的使用

UNION的使用 给出将多条查询语句组合成单个结果集&#xff0c;两个表对应的列数和数据类型必须相同 UNION操作符&#xff1a; 返回两个查询结果集的并集&#xff0c;并去除重复记录 UNION ALL操作符 返回两个查询的结果集的并集。不去掉两个结果集的重复部分&#xff0c;重…

【Linux】Linux信号产生,接受与处理机制

理解Linux信号产生&#xff0c;接受与处理机制 信号是Linux操作系统中一种用于进程间通信和异步事件处理的机制。在本文中&#xff0c;我们将结合Linux的源码&#xff0c;深入分析信号的产生、发送、接收和处理的底层原理。 文章目录 理解Linux信号产生&#xff0c;接受与处理…

一、QGroundControl地面站使用介绍

文章目录 环境功能介绍飞行视图规划视图飞机设置分析工具程序设置 连接飞机飞机设置分析工具飞行视图规划任务 总结参考 环境 QGroundControl V4.2.0PX4-Autopilot V1.3.0devGazebo 模拟无人机 功能介绍 飞行视图规划视图飞机设置分析工具程序设置 飞行视图 软件打开后为飞…

跟着鲁sir学CV_Opencv(10)卡尔曼滤波

简介 卡尔曼滤波器由鲁道夫卡尔曼&#xff08;Rudolf E. Klmn&#xff09;在1960年提出&#xff0c;广泛应用于导航系统、信号处理、机器人定位、金融等多个领域。 主要分为两阶段&#xff1a;预测与更新 贝叶斯滤波器 贝叶斯框架下&#xff1a;预测&#xff08;先验&#x…

楼道堆积物视觉识别监控系统

楼道堆积物视觉识别监控系统采用了AI神经网络和深度学习算法&#xff0c;楼道堆积物视觉识别监控系统通过摄像头实时监测楼道的情况&#xff0c;通过图像处理、物体识别和目标跟踪算法&#xff0c;系统能够精确地识别楼道通道是否被堆积物阻塞。楼道堆积物视觉识别监控系统检测…

K210的MicroPython扩展例程——自动驾驶例程(视觉循迹)

前言 该例程实现的功能是循迹功能&#xff0c;可为想拿K210做视觉循迹开发作为参考 例程使用前需要搭建好MicroPython的开发环境 K210开发板MicroPython开发环境搭建 一、将K210连接好后打开CanMV IDE&#xff0c;连接成功后&#xff0c;三角形变成绿色 二、然后要把小车驱动…

接口测试怎么测?为什么要做接口测试?

一、前言 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间及内部各个子系统之间的交互点。测试的重点是检查数据的交换、传递和控制管理过程&#xff0c;以及系统间的逻辑依赖关系等。 简单地说&#xff0c;接口测试就是通过URL向服务器或者…

leetCode-hot100-数组专题之区间问题

数组专题之区间问题 知识点&#xff1a;解决思路&#xff1a;例题56.合并区间57.插入区间253.会议室 Ⅱ485.无重叠区间 数组区间问题是算法中常见的一类问题&#xff0c;它们通常涉及对数组中的区间进行排序、合并、插入或删除操作。无论是合并区间、插入区间还是删除重复空间&…

azure gpt 技术教程教学 | 在Azure OpenAI 上部署GPT-4o

Azure OpenAI GPT-4o是OpenAI推出的最新旗舰级人工智能模型。GPT-4o模型设计为能够实时对音频、视觉和文本进行推理&#xff0c;这是迈向更自然人机交互的重要一步。该模型的一大特点是能够处理多种类型的数据输入和输出&#xff0c;包括文本、音频和图像&#xff0c;实现了跨模…