【LeetCode每日一题】——37.解数独

news2025/7/6 20:42:20

文章目录

  • 一【题目类别】
  • 二【题目难度】
  • 三【题目编号】
  • 四【题目描述】
  • 五【题目示例】
  • 六【解题思路】
  • 七【题目提示】
  • 八【时间频度】
  • 九【代码实现】
  • 十【提交结果】

一【题目类别】

  • 数组

二【题目难度】

  • 困难

三【题目编号】

  • 37.解数独

四【题目描述】

  • 编写一个程序,通过填充空格来解决数独问题。
  • 数独的解法需 遵循如下规则:
  • 数字 1-9 在每一行只能出现一次。
  • 数字 1-9 在每一列只能出现一次。
  • 数字 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”]]
    • 解释:输入的数独如上图所示,唯一有效的解决方案如下所示:
    • 在这里插入图片描述

六【解题思路】

  • 此题有难度,但是还是回溯的思想。回溯算法的模板如下:
void backTracking(参数)
{
	if(终止条件)
	{
		保存结果;
		return;
	}
	for(遍历从当前位置出发的所有“路径”)
	{
		保存“路径”节点;
		backTracking(所需参数);
		回溯处理,删除上一步保存的“路径”节点,准备进行新的递归
	}
}
  • 有了以上模板,我们只需要往里面填入解决这道题所需的“工具”,首先有几个定义我们要清楚:
    • row[i][digit]:表示digit这个数字出现在了第i行
    • col[j][digit]:表示digit这个数字出现在了第j列
    • block[i][j][dight]:表示digit这个数字出现在了第i、j块
    • valid:表示是否应该结束递归
    • spaces:存储需要填入数字的位置
  • 首先遍历整个二维数组,当我们遍历到某个位置:
    • 如果此位置是“.”:说明需要填入数字,那么将此位置存入spaces,准备填入数字
    • 如果此位置是数字:那将此行、此列和此块对应这个数字都置为true,也就是不能再出现这个数字了
  • 然后进入递归算法,这里面就简单了,就是上面模板写的过程,只需要判断当前数字是否出现在此行、此列和此块即可
  • 此外还需要注意真正的数字和数组下标之间的关系
  • 其他细节可以参考代码
  • 最后不需要返回值

七【题目提示】

  • b o a r d . l e n g t h = = 9 board.length == 9 board.length==9
  • b o a r d [ i ] . l e n g t h = = 9 board[i].length == 9 board[i].length==9
  • b o a r d [ i ] [ j ] 是 一 位 数 字 或 者 ′ . ′ board[i][j] 是一位数字或者 '.' board[i][j].
  • 题 目 数 据 保 证 输 入 数 独 仅 有 一 个 解 题目数据 保证 输入数独仅有一个解

八【时间频度】

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n为输入数组的行数/列数
  • 空间复杂度: O ( 1 ) O(1) O(1)

九【代码实现】

  1. Java语言版
package Array;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: IronmanJay
 * @Description: 37.解数独
 * @CreateTime: 2022-11-26  09:36
 */
public class p37_SudokuSolver {

    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'}};
        solveSudoku(board);
    }

    private static boolean[][] row = new boolean[9][9];
    private static boolean[][] col = new boolean[9][9];
    private static boolean[][][] block = new boolean[3][3][9];
    private static boolean valid = false;
    private static List<int[]> spaces = new ArrayList<int[]>();

    public static void solveSudoku(char[][] board) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] == '.') {
                    spaces.add(new int[]{i, j});
                } else {
                    int digit = board[i][j] - '0' - 1;
                    row[i][digit] = true;
                    col[j][digit] = true;
                    block[i / 3][j / 3][digit] = true;
                }
            }
        }
        dfs_back_p37_SudokuSolver(board, 0);
    }

    public static void dfs_back_p37_SudokuSolver(char[][] board, int pos) {
        if (pos == spaces.size()) {
            valid = true;
            return;
        }
        int[] space = spaces.get(pos);
        int i = space[0];
        int j = space[1];
        for (int digit = 0; digit < 9 && !valid; digit++) {
            if (!row[i][digit] && !col[j][digit] && !block[i / 3][j / 3][digit]) {
                row[i][digit] = true;
                col[j][digit] = true;
                block[i / 3][j / 3][digit] = true;
                board[i][j] = (char) (digit + '0' + 1);
                dfs_back_p37_SudokuSolver(board, pos + 1);
                row[i][digit] = false;
                col[j][digit] = false;
                block[i / 3][j / 3][digit] = false;
            }
        }
    }

}
  1. C语言版
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

bool row[9][9];
bool col[9][9];
bool block[3][3][9];
bool valid;
int* spaces[81];
int spaceSize;

void dfs_back_p37_SudokuSolver(char** board, int pos)
{
	if (pos == spaceSize)
	{
		valid = true;
		return;
	}
	int i = spaces[pos][0];
	int j = spaces[pos][1];
	for (int digit = 0; digit < 9 && !valid; digit++)
	{
		if (!row[i][digit] && !col[j][digit] && !block[i / 3][j / 3][digit])
		{
			row[i][digit] = true;
			col[j][digit] = true;
			block[i / 3][j / 3][digit] = true;
			board[i][j] = digit + '0' + 1;
			dfs_back_p37_SudokuSolver(board, pos + 1);
			row[i][digit] = false;
			col[j][digit] = false;
			block[i / 3][j / 3][digit] = false;
		}
	}
}

void solveSudoku(char** board, int boardSize, int* boardColSize)
{
	memset(row, false, sizeof(row));
	memset(col, false, sizeof(col));
	memset(block, false, sizeof(block));
	valid = false;
	spaceSize = 0;
	for (int i = 0; i < 9; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			if (board[i][j] == '.')
			{
				spaces[spaceSize] = malloc(sizeof(int) * 2);
				spaces[spaceSize][0] = i;
				spaces[spaceSize++][1] = j;
			}
			else
			{
				int digit = board[i][j] - '0' - 1;
				row[i][digit] = true;
				col[j][digit] = true;
				block[i / 3][j / 3][digit] = true;
			}
		}
	}
	dfs_back_p37_SudokuSolver(board, 0);
}

/*主函数省略*/

十【提交结果】

  1. Java语言版
    在这里插入图片描述

  2. C语言版
    在这里插入图片描述

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

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

相关文章

抢先看!阿里发布2023最新版分布式核心小册,GitHub标星破已千万

什么是分布式 一个分布式系统你可以看做是一组计算机系统一起工作&#xff0c;而在终端用户的视角看过去&#xff0c;就像一台计算机在工作一样 。 这组一起工作的计算机&#xff0c;拥有共享的状态 &#xff0c;他们同时运行&#xff0c;独立机器的故障不会影响整个系统的正常…

1、认识时间复杂度和简单的排序算法

目录时间复杂度选择排序冒泡排序异或交换解释案例综上插入排序二分查找拓展对数器时间复杂度 如果一个操作时间和数据量没有关系&#xff0c;则是常数时间的操作 比如一个数组arr[n]这就是算一个偏移量&#xff0c;然后找到这个位置的值&#xff0c;这就是常数时间&#xff0c…

力扣(LeetCode)882. 细分图中的可到达节点(C++)

spfa 将边细分成节点&#xff0c;如果一条边细分出 nnn 个结点&#xff0c;那么边的两个端点距离 n1n1n1 &#xff0c;边长 n1n1n1。提示中给出&#xff0c;一共 300030003000 个初始结点&#xff0c;无向边的数目小于等于 100001000010000 &#xff0c;这是提示我们最多有 20…

服务器怎么远程连接控制

服务器怎么远程连接控制 我是艾西&#xff0c;还是有很多小白同学问我服务器怎么远程连接。那么今天我们重点来教教大家如何用电脑远程服务器配上图文教程&#xff0c;让不懂的新手小白一看就会&#xff0c;分分钟上手教程 远程服务器需要一台电脑俗称“PC”就是我们自己平时经…

红外遥控视力自动检测系统的设计与实现

红外线视力检测系统的设计与实现 实现方法 分为两部分 上位机-------------串口通讯-------------下位机 上位机&#xff1a;使用LabVIEW软件编写窗口软件。 串口通讯&#xff1a;USB线进行链接通讯。 下位机&#xff1a;AT89C52单片机开发板 说明&#xff1a;Labvi…

46-pytest-分布式插件pytest-xdist使用

分布式插件pytest-xdist使用前言安装插件分布式用例设计原则使用示例测试报告按一定顺序执行前言 本篇来学习下在pytest中分布式执行测试用例&#xff0c;以节省测试时间。 安装插件 pip install pytest-xdist分布式用例设计原则 用例之间是独立的&#xff0c;用例之间没有…

学生护眼台灯哪个牌子最好?2022双十二4款儿童护眼写字灯推荐

现在的孩子学业压力越来越大了&#xff0c;眼睛也是长期高强度使用&#xff0c;不堪重负&#xff0c;如果不注意保护&#xff0c;加上年龄偏小身体器官尚未发育完全&#xff0c;极易出现各种眼睛问题。所以对于经常晚上看书写字的学生群体来说&#xff0c;有一个健康护眼的照明…

OpenGL ES 学习(二) -- 渲染模式和GLSL

上一章&#xff0c;我们学习了 OpenGL 的基本知识&#xff0c;这一章&#xff0c;一起学习OpenGL的渲染模式和渲染语言GLSL。 一. 渲染流程 OpenGL的渲染流程如下图所示&#xff1a; 从这里看出&#xff0c;OpenGL 需要使用顶点着色器&#xff0c;先绘制好轮廓&#xff0c;再…

Java面向对象之——多态

文章目录一、多态的概念二、多态的条件三、重写四、向上转型和向下转型1、向上转型2、向下转型五、再谈多态六、多态的优缺点总结一、多态的概念 多态是同一个行为具有多个不同表现形式或形态的能力。就比如人吃饭&#xff0c;对于中国人使用筷子吃饭&#xff0c;美国人使用刀…

C. Almost All Multiples(贪心 + 思维)

Problem - C - Codeforces 给定两个整数n和x&#xff0c;如果pi是i的倍数&#xff0c;所有1≤i≤n-1&#xff0c;pn1&#xff0c;且p1x&#xff0c;则长度为n的排列组合† p被称为搞笑。 找出最小的有趣的排列组合&#xff0c;或报告说不存在这样的排列组合。 † 长度为n的排…

分布式学习必看:十年架构大佬带你从零开始学习分布式服务框架!

前言 最近在看《架构探险-从零开始写分布式服务框架》&#xff0c;对于分布式框架的入门级选手还是挺合适的&#xff0c;扫盲。对分布式服务框架中的基本概念&#xff1a;RPC、SOA、序列化、Spring集成RPC、ZooKeeper、I/O模型、Netty、软负载、服务治理做了系统介绍。手写了R…

【知识网络分析】引文网络(citation)

引文网络(citation) 1 读取本地文献并构建引文网络数据集2 网络数据集精简3 剔除孤立点方法封装4 网络图美化5 社团群体划分并结合色谱图显示6 网络节点中心度相关指标计算1 读取本地文献并构建引文网络数据集 新建一个notebook文件后,导入需要使用的包,本案例使用WOS数据…

进程、线程、 Thread类的基本用法 【javaee】

目录 一、什么是进程/任务&#xff08;Process/Task&#xff09; 二、什么是线程&#xff08;Thread&#xff09; 三、进程和线程的区别 四、创建线程的方法&#xff1a; 方法1 继承 Thread &#xff0c;重写run 方法2 实现 Runnable 接口 方法3 匿名内部类创建 Thread …

数据库的常用操作

数据库的分类 数据库大体可以分为 关系型数据库 和 非关系型数据库 关系型数据库&#xff1a;是指采用了关系模型来组织数据的数据库&#xff0c;关系模型指的就是二维表格模型&#xff0c;关系型数据库都基于标准的SQL&#xff0c;只是内部一些实现有区别 常见关系型数据库…

奇舞周刊第 473 期: Rollup 与 Webpack 的 Tree-shaking

记得点击文章末尾的“ 阅读原文 ”查看哟~下面先一起看下本期周刊 摘要 吧~奇舞推荐■ ■ ■Rollup 与 Webpack 的 Tree-shakingRollup 和 Webpack 是目前项目中使用较为广泛的两种打包工具&#xff0c;去年发布的 Vite 中打包所依赖的也是 Rollup&#xff1b;在对界面加载效率…

Java项目:JSP手机商城管理系统包含前台

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台&#xff0c;分为管理员与普通用户两种角色&#xff0c;管理员登录后台&#xff0c;普通用户登录前台&#xff1b; 管理员角色…

编译原理之词法分析器随笔和简单实现

借鉴: 编译原理之美. 极客时间上 什么是词法分析 编译原理&#xff1a;词法分析简单的来说就是在字符串中提取一系列的word单词. 编译器的眼里, 我们的一切输入都是什么? 都是一个一个的字符串. 所以编译器干的就是字符串解析工作. 词法分析&#xff1a;自然就是解析出来…

Vue中el和data的写法与 MVVM模型

目录 el和data的两种写法 el的两种写法 data的两种写法 data与el的写法小结 MVVM模型 MVVM模型小结 el和data的两种写法 el的两种写法 <body> <div id"root"> hello,{{name}}</div><script type"text/javascript">const vm ne…

iwebsec靶场 SQL注入漏洞通关笔记3- bool注入(布尔型盲注)

系列文章目录 iwebsec靶场 SQL注入漏洞通关笔记1- 数字型注入_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记2- 字符型注入&#xff08;宽字节注入&#xff09;_mooyuan的博客-CSDN博客 目录 文章目录 前言 一、源码分析 二、sqlmap渗透 1.注入命令 2.完整交互过程…

小技巧1:如何给pip install进行换源

大家好&#xff0c;我是Kamen Black君&#xff0c;今天给大家介绍一个小技巧&#xff1a;如何给pip安装进行换源。 print("祝大家每天快乐&#xff0c;love and peace&#xff01;") 曾几何时&#xff0c;当我准备好了一段很有趣的代码准备进行运行时&#xff0c;发…