力扣第三十七题——解数独

内容介绍

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

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

  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] 是一位数字或者 '.'
  • 题目数据 保证 输入数独仅有一个解

完整代码

 bool line[9][9];
bool column[9][9];
bool block[3][3][9];
bool valid;
int* spaces[81];
int spacesSize;void dfs(char** board, int pos) {if (pos == spacesSize) {valid = true;return;}int i = spaces[pos][0], j = spaces[pos][1];for (int digit = 0; digit < 9 && !valid; ++digit) {if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) {line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;board[i][j] = digit + '0' + 1;dfs(board, pos + 1);line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;}}
}void solveSudoku(char** board, int boardSize, int* boardColSize) {memset(line, false, sizeof(line));memset(column, false, sizeof(column));memset(block, false, sizeof(block));valid = false;spacesSize = 0;for (int i = 0; i < 9; ++i) {for (int j = 0; j < 9; ++j) {if (board[i][j] == '.') {spaces[spacesSize] = malloc(sizeof(int) * 2);spaces[spacesSize][0] = i;spaces[spacesSize++][1] = j;} else {int digit = board[i][j] - '0' - 1;line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;}}}dfs(board, 0);
}

思路详解

方法概述

  • solveSudoku:主方法,初始化数据结构并调用DFS方法来填充数独板。
  • dfs:递归方法,用于尝试填充数独板的每个空格。

数据结构

  • line:一个二维布尔数组,用于标记每行中每个数字是否已经被使用。
  • column:一个二维布尔数组,用于标记每列中每个数字是否已经被使用。
  • block:一个三维布尔数组,用于标记每个3x3宫格中每个数字是否已经被使用。
  • valid:一个布尔变量,用于标记是否已经找到有效的数独解决方案。
  • spaces:一个指针数组,用于存储所有空格的位置。
  • spacesSize:一个整数,用于记录空格的数量。

解题步骤

初始化
  1. 使用memset函数将linecolumnblock数组初始化为false,表示所有数字都未被使用。
  2. valid变量设置为false,表示尚未找到解决方案。
  3. 遍历数独板,对于每个元素:
    • 如果是空格(即’.'),则记录该空格的位置到spaces数组,并增加spacesSize
    • 如果是非空格,则更新linecolumnblock数组,标记该数字已被使用。
深度优先搜索(DFS)
  1. 递归方法dfs接收当前填充空格的位置pos
  2. 如果pos等于spacesSize,说明所有空格都已填充,设置validtrue并返回。
  3. 对于当前空格位置,尝试填充数字1到9:
    • 检查当前数字是否在当前行、当前列和当前3x3宫格中未被使用。
    • 如果未被使用,则更新linecolumnblock数组,将当前数字标记为已使用,并在数独板上填充该数字。
    • 递归调用dfs,尝试填充下一个空格。
    • 如果递归调用后未找到解决方案,则回溯,撤销当前数字的填充,并继续尝试下一个数字。
解决方案
  • 如果在DFS过程中找到了有效的解决方案,valid将被设置为true,数独板将被填充完成。
  • 如果所有可能的填充方式都尝试过后仍未找到解决方案,则数独无解。

总结

这段代码通过深度优先搜索算法和回溯策略来解决问题。它通过递归地尝试填充每个空格,并在每一步都检查是否违反了数独的规则,从而找到有效的解决方案。通过使用布尔数组来跟踪每个数字的使用情况,代码能够高效地进行检查和回溯。

知识点精炼

  1. 深度优先搜索(DFS)

    • 使用递归方法实现DFS,探索数独所有可能的填充组合。
  2. 回溯算法

    • 在DFS中应用回溯,撤销之前的填充以探索新的可能性。
  3. 布尔数组

    • 使用布尔数组linecolumnblock来跟踪每个数字在行、列和宫格中的使用情况。
  4. 数独规则

    • 确保每行、每列和每个3x3宫格内的数字1至9不重复。
  5. 数组初始化

    • 使用memset函数初始化布尔数组,确保所有值初始为false
  6. 动态内存分配

    • 使用mallocspaces数组分配内存,存储空格位置。
  7. ASCII转换

    • 通过字符与整数的ASCII转换,实现字符数字与整数的相互转换。
  8. 索引计算

    • 使用数组索引来访问和更新行、列和宫格的状态。
  9. 递归终止条件

    • 当所有空格都被填充时,递归终止,并标记找到有效解决方案。
  10. 状态重置

    • 在回溯过程中,撤销对行、列和宫格状态的更改,以便探索其他可能的填充。
  11. 全局变量

    • 使用全局变量valid来标记是否找到解决方案,以及spacesSize来跟踪空格数量。

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CVE-2024-39700 (CVSS 9.9):JupyterLab 模板中存在严重漏洞

在广泛使用的 JupyterLab 扩展模板中发现了一个严重漏洞&#xff0c;编号为CVE-2024-39700 。此漏洞可能使攻击者能够在受影响的系统上远程执行代码&#xff0c;从而可能导致大范围入侵和数据泄露。 该漏洞源于在扩展创建过程中选择“测试”选项时自动生成“update-integratio…

VIM基础配置

1. CTAGS配置 下载 上传虚拟机&#xff0c;解压&#xff0c;进入目录 tar -xzvf ctags-5.8.tar.gz cd ctags-5.8/编译 ./configure sudo make sudo make install查看是否安装成功 ctags --version打印如下 2. 使用Vundle 下载 git clone https://github.com/VundleVim/Vund…

Linux并发程序设计(3):守护进程

目录 前言 一、介绍 1.1 概念 1.2 特点 1.3 举例 二、系统编程 2.1 setsid函数 2.2 getpid函数 2.3 getsid函数 2.4 getpgid函数 2.5 chdir函数 三、代码例程 3.1 使子进程在后台运行 3.2 使子进程脱离原终端 3.3 更换目录&#xff0c;并设定权限&#xff08;非…

基于STM32通过云平台实现智慧大棚【手机远程查看温湿度】【报警】

文章目录 一、成果演示二、所用到的模块三、实现的功能四、接线说明五、WIFI模块配置步骤5.1云平台介绍5.2云平台使用5.3使用USB转TTL测试联通云平台 六、STM32代码编写七、手机上查看数据6.1下载软件&#xff08;仅限安卓手机&#xff09;6.2操作 一、成果演示 STM32通过物联网…

String、StringBuffer和StringBuilder

一、String类 1. String类的理解 2. String类结构 1. String类实现了Serializable接口,说明String对象可以串行化,即可以在网络上传输 2. String类实现了Comparable接口,说明String对象可以比较 String底层是一个字符数组,这个数组里存的是字符串的内容 例如:…

005 仿muduo实现高性能服务器组件_通信连接管理

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;仿muduo &#x1f4d2;代码仓库&#xff1a; 项目代码 &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多知识 文章目录 前言Channel模块设计原因整体设计代码如下 Connection模块设计原…

Florence2:Advancing a unified representation for a variety of vision tasks

Florence-2模型:开启统一视觉基础模型的新篇章_florence -2-CSDN博客文章浏览阅读1.1k次,点赞108次,收藏109次。Florence-2是由微软Azure AI团队开发的一款多功能、统一的视觉模型。它通过统一的提示处理不同的视觉任务,表现出色且优于许多大型模型。Florence-2的设计理念是…

用Postman Flows打造你的专属API:外部公开,轻松上手!

引言 Postman Flows 是一个使用 GUI 进行无代码 API 调用流程创建的服务。这篇文章我尝试使用 Flows 来构建将 Momento Topic 中的数据保存到 TiDB 的保存 API&#xff0c;因此想分享一些使用过程中的技巧等。 实现内容 将从 Momento Topics 配发的 JSON 数据保存到 TiDB 中。…

C++ 栈( stack )学习

目录 1.栈 2.模拟栈 1.1.入栈( push ) 1.2.出栈( pop ) 1.3.获取栈顶元素( top ) 3.直接使用栈( stack ) 3.1.导入头文件并创建栈 3.2.栈的操作 3.2.1.入栈( push ) 3.2.2.出栈( pop ) 3.2.3.获取栈顶元素( top ) 3.2.4.获取栈中元素个数( size ) 3.2.5.判断栈是否…

代码随想录算法训练营day8 | 344.反转字符串、541.反转字符串 II、卡码网:54.替换数字

文章目录 344.反转字符串思路 541.反转字符串 II思路 卡码网&#xff1a;54.替换数字思路复习&#xff1a;字符串 vs 数组 总结 今天是字符串专题的第一天&#xff0c;主要是一些基础的题目 344.反转字符串 建议&#xff1a; 本题是字符串基础题目&#xff0c;就是考察 revers…

docker挂载部署reids6.2.1

1.拉取镜像 docker pull redis:6.2.12.创建挂在目录&#xff08;根据自己要求修改具体目录&#xff09; mkdir -p /home/admin/redis/{data,conf}3.在/home/admin/redis/conf目录下创建redis.conf文件 cd /home/admin/redis/conf touch redis.conf4.复制下面文本到redis.conf…

浅析JWT原理及牛客出现过的相关面试题

原文链接&#xff1a;https://kixuan.github.io/posts/f568/ 对jwt总是一知半解&#xff0c;而且项目打算写个关于JWT登录的点&#xff0c;所以总结关于JWT的知识及网上面试考察过的点 参考资料&#xff1a; Cookie、Session、Token、JWT_通俗地讲就是验证当前用户的身份,证明-…

不断把别人“装”进我们的灵魂口袋

嘿&#xff0c;朋友们&#xff01;今天我们来聊聊一种超酷的能量——本色示人。这不是什么秘密武器&#xff0c;但它比任何超能力都来得实在。 第一部分&#xff1a;本色示人&#xff0c;能量界的“超级赛亚人” 1.1 坦诚的超能力 想象一下&#xff0c;如果你的内心强大到可以…

Window部署Ollama+Qwen2.0+Open-WebUI

文章目录 Windows下安装Docker安装Docker检查是否安装成功, 出现版本即为安装成功安装Ollama启动 Ollama 并拉取模型(选做) 修改默认地址和端口(选做) Ollama 进行跨域配置安装open-webui Windows下安装Docker 准备条件 开启Hyper-V&#xff0c;在“启用或关闭Windows功能”里…

C语言 #指针数组 #数组指针 #数组参数、指针参数

文章目录 前言 一、指针数组 1、概念&#xff1a; 2、指针数组有什么用呢&#xff1f; 二、数组指针 1、数组指针的定义 2、数组名与 &数组名 的区别 3、数组指针如何初始化&#xff1f; 4、数组指针的用法 三、根据代码区分 指针数组 和 数组指针 四、数组参数、指针参数 …

Shell编程之正则表达式与文本三剑客

目录 一、正则表达式 1.引言--什么是正则表达式 1.1正则表达式的功能 2.基础正则表达式&#xff08;BRE&#xff09; 2.1特殊字符 2.2定位符 2.3非打印字符 3.扩展正则表达式(ERE) 4.元字符操作的案列 二、命令小工具 1.cut&#xff1a;列截取工具 2.sort排序 …

【Android】使用ViewPager2与TabLayout实现顶部导航栏+页面切换

【Android】使用ViewPager2与TabLayout实现顶部导航栏&#xff0b;页面切换 TabLayout与ViewPager2概述 TabLayout TabLayout 是 Android 支持库中的一个组件&#xff0c;它是 Design 支持库的一部分。TabLayout 提供了一个水平的标签页界面&#xff0c;允许用户在不同的视图…

CogVideo 实测,智谱「清影」AI视频生成,全民免费,连 API 都开放了!

不得不说&#xff0c;AI 视频生成界最近非常火热~ 前有快手「可灵」开放内测&#xff0c;一下子带火了老照片修复&#xff0c;全网刷屏&#xff1a; 怕是你还没拿到内测资格&#xff0c;被称为 “国货之光” 的「可灵」就结束了免费无限量模式。每天只有66点的免费额度&#x…

鸿蒙(API 12 Beta2版)【创建NDK工程】

创建NDK工程 下面通过DevEco Studio的NDK工程模板&#xff0c;来演示如何创建一个NDK工程。 说明 不同DevEco Studio版本的向导界面、模板默认参数等会有所不同&#xff0c;请根据实际工程需要&#xff0c;创建工程或修改工程参数。 通过如下两种方式&#xff0c;打开工程创…

2024-07-27 Unity Excel —— 使用 EPPlus 插件读取 Excel 文件

文章目录 1 前言2 项目地址3 使用方法3.1 写入 Excel3.2 读取 Excel3.3 读写 csv 文件 4 ExcelSheet 代码 1 前言 ​ 前几日&#xff0c;一直被如何在 Unity 中读取 Excel 的问题给困扰&#xff0c;网上搜索相关教程相对古老&#xff08;4、5 年以前了&#xff09;。之前想用 …