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

内容介绍

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

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

  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,一经查实,立即删除!

相关文章

每天一个数据分析题(四百四十四)- 数据仓库

企业数据仓库里面的数据一般是由业务数据经过ETL技术处理后来的&#xff0c;以下关于ETL的说法错误的是 A. ETL过程中的主要环节是数据抽取、数据转换和加工、数据流转 B. 增量数据抽取过程中&#xff0c;提取增量数据的方法有通过时间戳、建立触发器、全表比对、日志比对等 …

springboot整合pgsql

demo代码说明 springboot使用mybatis-plus整合pgsql 在springboot项目中使用pgsql&#xff0c;使用了mybatis-plus、druid 代码见 spring-demo: springboot 结合各种插件 demo 注意事项&#xff1a; 版本兼容 正常springboot使用&#xff0c;但是注意需要添加pgsql正确版…

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;非…

React--Redux

Redux 是一个用于 JavaScript 应用的状态管理库&#xff0c;特别是在 React 应用中非常流行。下面我将详细介绍一个使用 Redux 的简单案例&#xff0c;包括设置 Redux 环境、创建 store、定义 actions 和 reducers&#xff0c;以及如何连接 React 组件。 步骤 1: 安装依赖 首…

基于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 中。…

3086. 拾起 K 个 1 需要的最少行动次数

3086. 拾起 K 个 1 需要的最少行动次数 题目链接&#xff1a;3086. 拾起 K 个 1 需要的最少行动次数 代码如下&#xff1a; //参考链接:https://leetcode.cn/problems/minimum-moves-to-pick-k-ones/solutions/2692009/zhong-wei-shu-tan-xin-by-endlesscheng-h972 class Sol…

CrowdStrike引发全球微软系统大宕机:事故解析及网络安全反思

引言 近日&#xff0c;一次由CrowdStrike推送的更新引发了全球IT系统大规模故障。超过850万台电脑受到影响&#xff0c;涵盖各个行业和领域&#xff0c;引发了广泛关注和讨论。本文将详细解析此次事件的来龙去脉&#xff0c;评估其影响&#xff0c;并探讨网络安全的现状及未来…

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…

ChatGPT:宽列数据库是什么?

ChatGPT&#xff1a;宽列数据库是什么&#xff1f; 宽列数据库&#xff08;Wide-Column Store&#xff09;是一种 NoSQL 数据库&#xff0c;它的设计灵感来自于 Google 的 Bigtable。宽列数据库适用于处理大规模的分布式数据存储&#xff0c;特别是在需要高性能读写、灵活的数据…

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…

深入理解 Laravel 中的会话管理

引言 会话管理是 Web 应用中一个至关重要的功能&#xff0c;它允许应用识别并跟踪用户的会话状态。Laravel 提供了一个强大而灵活的会话管理系统&#xff0c;使得开发者可以轻松实现用户状态的跟踪和管理。本文将详细介绍 Laravel 中的会话管理机制&#xff0c;包括会话的创建…

浅析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;如果你的内心强大到可以…