LeetCode 37. 解数独

news2024/10/7 20:34:41

一、题目描述

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

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

数字 1-9每一行只能出现一次。
数字 1-9每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
在这里插入图片描述
输入: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 isValid(int row, int col, char val, vector<vector<char>>& board) 
{
	// 判断行里是否重复
    for (int i = 0; i < 9; i++) 
    { 
        if (board[row][i] == val) 
        {
            return false;
        }
    }
    // 判断列里是否重复
    for (int j = 0; j < 9; j++) 
    { 
        if (board[j][col] == val) 
        {
            return false;
        }
    }
    // 判断9方格里是否重复
    int startRow = (row / 3) * 3;//计算每一个九宫格起始的行和列
    int startCol = (col / 3) * 3;
    for (int i = startRow; i < startRow + 3; i++) 
    { 
        for (int j = startCol; j < startCol + 3; j++) 
        {
            if (board[i][j] == val ) 
            {
                return false;
            }
        }
    }
    //都不重复代表这个位置可以填该数字
    return true;
}

每一个数字如何判断的代码已经写好了,那么接下来如何去填数字,才能把所有的情况都试一遍呢?
那就是所有 需要填数字的位置都得遍历一遍,而且每一个位置都需要从 1~ 9 都试一遍
那么代码来了:

    for (int i = 0; i < board.size(); i++) // 遍历行
    {        
        for (int j = 0; j < board[0].size(); j++) // 遍历列
        { 
            if (board[i][j] == '.') //该位置为空,需要我们填数字
            {
                for (char k = '1'; k <= '9'; k++) //从 1 ~ 9 都逐个试
                {     
                    if (isValid(i, j, k, board)) // (i, j) 判断 k是否 可以放这个位置
                    {
                        board[i][j] = k;                // 放置k
                    }
                }
                return false;  // 9个数都试完了,都不行,那么就返回false 
            }                
        }
	}
	return true;

这样对吗?显然不对,这样只能得出来一组结果,无论成功与否都只看这一把了,属实离谱
例如这里,第一行第三列 除了填 1 还可以 填 2 、4
在这里插入图片描述
那么从该位置起 一共需要 循环 3 次,得到 3 个 9 × 9 结果(x 代表填入得数字,示例)
在这里插入图片描述
如果 其中每个 格子 1 - 9 都试过了都不行返回false,如果其中有一组适合则return true
而每一组得结果只需要一直递归下去即可,并且每个位置得每一个数字试完之后记得回溯,也就是试下一组数字

                    if (isValid(i, j, k, board)) 
                    {
                        board[i][j] = k;                // 放置k
                        if (backtracking(board)) //递归试每个位置的每一个数字
                        {
                        	return true// 如果找到合适一组立刻返回
                        }; 
                        board[i][j] = '.';              // 回溯,撤销k,接下来试下一个数字
                    }

三、代码实现

class Solution {
private:
bool backtracking(vector<vector<char>>& board) 
{
    for (int i = 0; i < board.size(); i++) // 遍历行
    {        
        for (int j = 0; j < board[0].size(); j++) // 遍历列
        { 
            if (board[i][j] == '.') 
            {
                for (char k = '1'; k <= '9'; k++) 
                {     
                    if (isValid(i, j, k, board)) // (i, j) 这个位置放k是否合适
                    {
                        board[i][j] = k;  // 放置k
                        if (backtracking(board)) //递归填每种情况的接下来每一个数字
                        {
                            return true;// 如果找到合适一组立刻返回
                        } 
                        board[i][j] = '.';  // 回溯,撤销k,接下来试下一个数字
                    }
                }
                return false;  // 9个数都试完了,都不行,那么就返回false 
            }                
        }
    }
    return true; // 遍历完没有返回false,说明找到了合适棋盘位置了
}
bool isValid(int row, int col, char val, vector<vector<char>>& board) {
    // 判断行里是否重复
    for (int i = 0; i < 9; i++) 
    { 
        if (board[row][i] == val) 
        {
            return false;
        }
    }
     // 判断列里是否重复
    for (int j = 0; j < 9; j++) 
    {
        if (board[j][col] == val) 
        {
            return false;
        }
    }
    // 判断9方格里是否重复
    int startRow = (row / 3) * 3;//计算每个3×3 宫格的起始行、列
    int startCol = (col / 3) * 3;
    for (int i = startRow; i < startRow + 3; i++) 
    { 
        for (int j = startCol; j < startCol + 3; j++) 
        {
            if (board[i][j] == val ) 
            {
                return false;
            }
        }
    }
    return true;
}
public:
    void solveSudoku(vector<vector<char>>& board) {
        backtracking(board);
    }
};

运行结果:
在这里插入图片描述

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

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

相关文章

如果重回大学时光

目录如果重回大学时光1. 多参加社团活动&#xff0c;结交更多的朋友2. 认真考虑专业分流方向3. 根据兴趣和能力选择适合自己的出路4. 为未来做好准备&#xff0c;规划职业发展如果重回大学时光 当前我是一名普通的码农&#xff0c;还有几个月&#xff0c;又将有一批大学生将毕…

vue实现美观大方的动漫、cos、帖子类型网站

一、先上效果图 1.项目demo预览&#xff1a;点击预览 参照半次元的榜单-绘画榜、榜单-COS榜、榜单-写作榜、个人中心、登录注册页面&#xff0c;导航栏等&#xff0c;分别实现页面排版、数据交互、基础框架布局搭建以及自定义vue组件合理的封装及使用。在vue项目开发过程中&a…

梦中情树---二叉树

前言&#xff1a; 今天就来讲树的一种特殊结构---二叉树 当然先来给大家看一张图片 看到这棵树了吗&#xff1f;它从根开始&#xff0c;每个结点都有且仅有两个分支&#xff0c;这个结构就是我们的二叉树。 其实我们上次讲的堆也可以看成一棵二叉树&#xff0c;但是人家的本质…

【python】Jupyter的使用(python代码编辑器)

文章目录一、Jupyter的介绍1、Jupyter是什么&#xff1f;2、Jupyter有什么独特之处&#xff1f;二、Jupyter的安装1、首先要下载python2、用pip命令下载Jupyter三、Jupyter的使用1、运行Jupyter2、简要介绍Jupyter的使用方法3、快捷键的使用四、总结一、Jupyter的介绍 1、Jupy…

安卓系统软键盘初步分析

初步分析的相关日志 复现log: 11-05 14:01:24.768 7991 7991 V InputMethodManager: onViewClicked: true 11-05 14:01:24.768 7991 7991 D InputMethodManager: showSoftInput() viewandroidx.appcompat.widget.AppCompatEditText{bd0acc9 VFED..CL. .F.P..ID 0,0-900,9…

C# 基础:创建、数据类型转换、基本运算符、

VS 快捷键 Ctri K D 代码整理 Ctri KM O 代码收缩 Ctri J 弹出提示 halcon 窗体应用 添加在线第三方库 右键项目名 --> 管理NuGet程序包 halcon 界面&#xff0c;创建选择 添加halcon离线动态链接库 右键引用 --> 添加引用 --> 选择动态链接库 .dll文件 导入…

22勤于思考:gRPC都有哪些优势和不足?

如果你能从专栏的开篇词开始读到这篇文章并且能够在过程中认真思考,那么我相信你目前已经能够对gRPC有了较为充分了解。在专栏的最后几节中,我们抽出一篇文章。来探讨一下gRPC有哪些优势和不足,因为只有这样我们才能取其精华,去其糟粕,学习gRPC框架设计的优点,还能反观出…

NLP领域顶级会议和期刊汇总(附CCF最新推荐目录)

研究NLP需要关注学术界or大厂AI Lab最新的科研动态&#xff0c;了解技术发展的趋势&#xff0c;写论文才能下笔如有神。找到了论文就能找到要复现的代码和要用到的数据集。 掌握科研动态也有助于提早做好产品规划以及技术预研。 对于NLPer而言&#xff0c;了解科研动态最好的方…

总结:网卡

一、背景 经常听到eth0&#xff0c;bond0这些概念&#xff0c;好奇他们的区别&#xff0c;于是有了此篇文章记录下。 二、介绍 网卡&#xff1a;即网络接口板&#xff0c;又称网络适配器或NIC (网络接口控制器)&#xff0c;是一块被设计用来允许计算机在计算机网络上进行通讯…

一把LOL的时间我入门了Go语言

走进 Go 语言~ 前言&#xff1a; Go 语言是由 Google 公司推出的一款新的编程语言&#xff0c;作为谷歌的亲儿子&#xff0c;发展势头迅猛&#xff0c;各个大厂目前都在积极推进 Go 语言的使用。Go 是云计算、云原生、区块链等众多前沿领域的首推语言&#xff0c;目前流行的 …

RocketMQ-01

1. MQ介绍 1.1 为什么要用MQ 消息队列是一种“先进先出”的数据结构 其应用场景主要包含以下3个方面 应用解耦 系统的耦合性越高&#xff0c;容错性就越低。以电商应用为例&#xff0c;用户创建订单后&#xff0c;如果耦合调用库存系统、物流系统、支付系统&#xff0c;任…

Python学习笔记--数据容器

&#xff08;一&#xff09; 数据容器入门 1. 数据容器&#xff1a;一种可以容纳多份数据的数据类型&#xff0c;容纳的每一份数据称之为一个元素。每一个元素&#xff0c;可以是任意类型的数据&#xff0c;如字符串、数字、布尔等。 2.. 种类&#xff1a;list&#xff08;列表…

MongoDB:常见的面试题和答案

1. 什么是MongoDB&#xff1f; MongoDB是一种非关系型数据库&#xff0c;被广泛用于大型数据存储和分布式系统的构建。MongoDB支持的数据模型比传统的关系型数据库更加灵活&#xff0c;支持动态查询和索引&#xff0c;也支持BSON格式的数据存储&#xff0c;这种格式可以支持读…

Go语言流处理,工厂模式,命令参数,序列化,单元测试

IO流 流就是数据在数据源和程序之间经历的路径。数据源可以是文件数据库或者键盘输入等&#xff0c;程序是运行在内存中的应用。 数据从数据源输入到程序的路径为输入流&#xff0c;从内存输出到数据源的路径为输出流。 流是以内存为核心&#xff0c;输入到内存就是输入流&am…

网络原理——IP地址与mac地址

目录 IP地址 IP地址 IP地址的组成 子网掩码 mac地址 冲突域与广播域 数据传输流程 IP地址 IP地址 互联网协议地址。每一个联网的主机都会分配一个IP地址。为32位二进制数&#xff0c;用4个.均分为四部分&#xff0c;在命令提示符中输入&#xff1a;ipconfig命令&#…

35岁的测试工程师被公司强行辞退,感叹道:我以前就该好好努力了

曾经的高薪软件测试工程师&#xff0c;今年35岁了&#xff0c;被公司劝退了&#xff0c;外卖跑到凌晨&#xff0c;很累&#xff0c;但还是有一种想诉说的冲动。哪怕让大家觉得已经说得太多了&#xff0c;烦了&#xff0c;都成祥林嫂了&#xff0c;但是&#xff0c;我是真的想说…

如何报名2023年CDGP数据治理专家认证?看这里

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

java中必会String的常用方法(IT枫斗者)

java中必会String的常用方法&#xff08;IT枫斗者&#xff09; 概述 在Java语言中&#xff0c;所有类似“ABC”的字面值&#xff0c;都是String类的实例&#xff1b;String类位于java.lang包下&#xff0c;是Java语言的核心类&#xff0c;提供了字符串的比较、查找、截取、大小…

NumPy 初学者指南中文第三版:6~10

原文&#xff1a;NumPy: Beginner’s Guide - Third Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 六、深入探索 NumPy 模块 NumPy 具有许多从其前身 Numeric 继承的模块。 其中一些包具有 SciPy 对应版本&#xff0c;可能具有更完整的功能。 我们将在下一章…

教你用Python和wxPython模块打造一个ChatGPT式打字效果程序

应用场景&#xff0c;可以使用类似ChatGPT回复的打字效果来增强用户体验或提高应用程序的可读性&#xff1a; 聊天机器人&#xff1a;当聊天机器人回复用户消息时&#xff0c;使用打字效果可以更好地模拟真实聊天体验&#xff0c;增强用户对聊天机器人的信任感。电子邮件客户端…