力扣37. 解数独(java回溯解法)

news2024/11/19 7:40:34

Problem: 37. 解数独

文章目录

  • 题目描述
  • 思路
  • 解题方法
  • 复杂度
  • Code

题目描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述

思路

该题可以使用回溯来模拟穷举。回溯问题通常涉及到可选列表,决策阶段,决策路径,而对于本题目我们选择将棋盘的每一个格子作为决策阶段,为此我们应该解决如何判断当前棋盘格子位置处是否可以放置1~9中的一个数字,为此我们可以:

1.若当前棋盘格子位置处已经存在数字,则直接递归下一个格子,但是当此时的格子属于棋盘的边缘时,要注意换行,当决策阶段等于9时说明已经找到一个解;
2.当当前棋盘格子位置处为空格,判断当前位置可填的数字将其填写到当前格子,并递归下一个格子(若格子为棋盘边缘,处理同上),最后将当前的格子复原!
3.我们可以定义三个boolean类型的的数组:

3.1boolean[][] rows = new boolean[9][10];用于辅助记录棋盘某一行上存在1-9中的某个数字,例如rows[2][2]表示棋盘第二行存在数字2;
3.2boolean[][] cols = new boolean[9][10];用于辅助记录棋盘某一列上存在1-9中的某个数字,例如cols[2][2]表示棋盘第二列存在数字2;
3.3boolean[][][] blocks = new boolean[3][3][10];用于辅助记录9x9棋盘某一个3x3的小矩形区间是否存在1-9中的某个数字,例如blocks[1][1][1]表示以3x3的小矩形为一个小数组(假设可以看作一个小数组)的大的二维数组中的第一行第一列中存在数字1。进一步我们容易得到若实际的棋盘中的一个格子的小标为(i,j)则对应到blocks中为(i/3,j/3);

解题方法

1.定义如思路中的三个boolean类性的辅助数组,并定义一个全局变量solved初始化为false,用于记录是否已经找到了一个解(因为题目只需要找到一个解即可)
2.将棋盘中本存在的数字填入棋盘,并将三个辅助数组对应位置设置为true(表示该行、该列、该3x3区域已经存在某个数字)
3.回溯函数:由参数row(棋盘当前行)与col(棋盘当前列)共同确定决策阶段

3.1当row == 9时表示已经找到一组解,则将solved置为true并返回;
3.2若当前格子已经存在数字则找处当前格子的下一个格子(也就是当前决策阶段的下一个决策阶段)若col不等于8(由于棋盘是9x9的棋盘则棋盘边缘位置的col等于8)时,直接右移动一个位置,否则直接换到下一行,并直递归处理下一决策阶段,若此时solved已经为true则直接返回即可。
3.3若当前格子为空格则利用for循环并结合三个辅助数组判断并将合适的数填写到当前格子,并同上处理下一个格子,同理若solved为true则直接返回,最后将当前格子(决策阶段)复原!!!

复杂度

时间复杂度:

最坏时间复杂度, O ( n n 2 ) O(n^{n^2}) O(nn2)其中n为棋盘的大小

空间复杂度:

O ( n 2 ) O(n^2) O(n2)其中n为棋盘的大小

Code

class Solution {
    //Array used to aid judgment
    private boolean[][] rows = new boolean[9][10];
    private boolean[][] cols = new boolean[9][10];
    private boolean[][][] blocks = new boolean[3][3][10];
    //Judgment for early exit recursion
    private boolean solved = false;

    /**
     *
     * @param board
     */
    public void solveSudoku(char[][] board) {
        //Initializes the data in the chessboard
        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (board[i][j] != '.') {
                    int num = board[i][j] - '0';
                    //Set to true in the array used for auxiliary judgment
                    rows[i][num] = true;
                    cols[j][num] = true;
                    blocks[i/3][j/3][num] = true;
                }
            }
        }
        backtrack(0, 0, board);
    }

    private void backtrack(int row, int col, char[][] board) {
        //End condition
        if (row == 9) {
            solved = true;
            return;
        }
        /*
        Process each cell on the board (the backtracking decision stage)
         by moving directly to the next cell in the same row
         if it is on the same row and not on the edge of the board,
         otherwise wrap the line
         */
        if (board[row][col] != '.') {
            int nextRow = row;
            int nextCol = col + 1;
            //On the edge
            if (col == 8) {
                //wrap the line
                nextRow = row + 1;
                nextCol = 0;
            }
            //Recursive next stage
            //The current cell has been filled with numbers
            backtrack(nextRow, nextCol,board);
            //Found a solution. Exit the recursion early
            if (solved) {
                return;
            }
        } else {
            for (int num = 1; num <= 9; ++num) {
                if (!rows[row][num] && !cols[col][num] && !blocks[row/3][col/3][num]) {
                    //Converts numbers to characters and fills them into the current cell
                    board[row][col] = String.valueOf(num).charAt(0);
                    rows[row][num] = true;
                    cols[col][num] = true;
                    blocks[row/3][col/3][num] = true;
                    int nextRow = row;
                    int nextCol = col + 1;
                    if (col == 8) {
                        nextRow = row + 1;
                        nextCol = 0;
                    }
                    backtrack(nextRow, nextCol, board);
                    if (solved) {
                        return;
                    }
                    //Recover the decision stage
                    board[row][col] = '.';
                    rows[row][num] = false;
                    cols[col][num] = false;
                    blocks[row/3][col/3][num] = false;
                }
            }
        }
    }
}

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

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

相关文章

OrangePi ZERO2 刷机与启动

镜像准备 用读卡器和Win32Diskimager刷写镜像到内存卡&#xff0c;镜像文件见下面百度云链接&#xff1a;https://pan.baidu.com/s/14aKTznc4Jvw4SoFF54JUTg 提取码&#xff1a;1815 刷写完毕后插回香橙派 串口登录 用MobaXterm和USB-TTL进行串口登录&#xff0c;MobaXterm软…

【C】⽂件操作

1. 为什么使⽤⽂件&#xff1f; 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运⾏程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进⾏持久化…

【文件上传系列】No.1 大文件分片、进度图展示(原生前端 + Node 后端 Koa)

分片&#xff08;500MB&#xff09;进度效果展示 效果展示&#xff0c;一个分片是 500MB 的 分片&#xff08;10MB&#xff09;进度效果展示 大文件分片上传效果展示 前端 思路 前端的思路&#xff1a;将大文件切分成多个小文件&#xff0c;然后并发给后端。 页面构建 先在页…

将RK3399的挖掘机开发板在Android10下设置系统默认为24小时制

将RK3399的挖掘机开发板在Android10下设置系统默认为24小时制 2023/12/9 22:07 应该也可以适用于RK3399的Android12系统 --- a/frameworks/base/packages/SettingsProvider/res/values/defaults.xml b/frameworks/base/packages/SettingsProvider/res/values/defaults.xml -2…

智能优化算法应用:基于静电放电算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于静电放电算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于静电放电算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.静电放电算法4.实验参数设定5.算法结果6.参考…

2023年9月13日 Go生态洞察:WASI支持在Go中的实现

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

C++新经典模板与泛型编程:策略类模板

策略类模板 在前面的博文中&#xff0c;策略类SumPolicy和MinPolicy都是普通的类&#xff0c;其中包含的是一个静态成员函数模板algorithm()&#xff0c;该函数模板包含两个类型模板参数。其实&#xff0c;也可以把SumPolicy和MinPolicy类写成类模板—直接把algorithm()中的两…

基于Lucene的全文检索系统的实现与应用

文章目录 一、概念二、引入案例1、数据库搜索2、数据分类3、非结构化数据查询方法1&#xff09; 顺序扫描法(Serial Scanning)2&#xff09;全文检索(Full-text Search) 4、如何实现全文检索 三、Lucene实现全文检索的流程1、索引和搜索流程图2、创建索引1&#xff09;获取原始…

案例057:基于微信小程序的马拉松报名系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

教师需要什么技能?

作为一名老师&#xff0c;需要掌握许多技能&#xff0c;以便能够成功地教育和指导学生。以下是一些关键技能&#xff1a; 1.教学技能&#xff1a;老师需要有深入的学科知识和教学经验&#xff0c;以便能够有效地传授知识。教师应该了解如何设计和执行教学计划&#xff0c;制定课…

点云 ros PointCloud2格式与livox CustomMsg格式介绍

点云 ros PointCloud2格式与livox CustomMsg格式介绍 PointCloud2 点云格式livox CustomMsg 点云格式 PointCloud2 点云格式 PointCloud2 是ros的一种点云格式 具体官方数据 http://docs.ros.org/en/jade/api/sensor_msgs/html/msg/PointCloud2.html std_msgs/Header header…

基于JavaWeb+SSM+Vue居住证申报系统小程序的设计和实现

基于JavaWebSSMVue居住证申报系统小程序的设计和实现 源码获取入口KaiTi 报告Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 KaiTi 报告 1.1题目背景 随着时代的发展&#xff0c;人口流动越来越频繁&#xff0…

uc_15_TCP协议

1 TCP协议 TCP提供客户机与服务器的链接。一个完整TCP通信过程需要经历三个阶段 1&#xff09;首先&#xff0c;客户机必须建立与服务器的连接&#xff0c;所谓虚电路 2&#xff09;然后&#xff0c;凭借已建立好的连接&#xff0c;通信双方相互交换数据 3&#xff09;最后&am…

python爬虫T1——urllib的基本使用 获取百度网页的源代码

文章目录 代码以及解释效果 代码以及解释 import urllib.request #使用urllib来获取百度的源码 urlhttps://zhuanlan.zhihu.com/p/357258757 #定义一个url 目标访问地址 responseurllib.requesturllib.request.urlopen(url) #模拟浏览…

有什么进销存软件能对接微信小程序?

有什么进销存软件能对接微信小程序&#xff1f; 据我所知&#xff0c;很多进销存软件都有配套的微信小程序吧。 以我们现在用的这个为例&#xff0c;这也是同行推荐过来的&#xff0c;很好用&#xff0c;而且性价比很高—— 在线平台&#xff0c;无需下载APP&#xff0c;搭载…

【小沐学Python】Python实现语音识别(Whisper)

文章目录 1、简介1.1 whisper简介1.2 whisper模型 2、安装2.1 whisper2.2 pytorch2.3 ffmpeg 3、测试3.1 命令测试3.2 代码测试&#xff1a;识别声音文件3.3 代码测试&#xff1a;实时录音识别 结语 1、简介 https://github.com/openai/whisper 1.1 whisper简介 Whisper 是…

C语言-字符串操作函数-附加使用方式

文章目录 前言字符串复制-strcpy字符串复制&#xff08;按照位数&#xff09;-strncpy字符串比较-strcmp字符串比较(按照位数)-strncmp不区分大小写的字符串比较-strcasecmp不区分大小写的比较(前n位)-strncasecmp字符串按照格式写入-sprintf字符串按照格式和个数写入-snprintf…

Leetcode—2646.最小化旅行的价格总和【困难】

2023每日刷题&#xff08;五十三&#xff09; Leetcode—2646.最小化旅行的价格总和 算法思想 看灵神的 实现代码 class Solution { public:int minimumTotalPrice(int n, vector<vector<int>>& edges, vector<int>& price, vector<vector&l…

Win10的SVN Adapter V1.0 中黄色感叹号 -- 解决

大部分都问题都可以通过&#xff1a; 关闭 SVN Adapter V1.0 在下载最新的 SVNDrv.sys替换 C:\Windows\System32\drivers 中的同名文件启动 SVN Adapter V1.0 就能成功 但是部分人的电脑 SVN Adapter V1.0 是有感叹号的&#xff0c;说明注册表有问题 先用 CCleaner 修复注册表…

解决npm install时报:gyp ERR! configure error

报错内容&#xff1a; npm ERR! gyp ERR! cwd C:\Users\zccbbg\code\my\examvue\node_modules\node-sass npm ERR! gyp ERR! node -v v16.13.1 npm ERR! gyp ERR! node-gyp -v v3.8.0 npm ERR! gyp ERR! not ok npm ERR! Build failed with error code: 1 解决办法&#xff1a;…