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

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.mfbz.cn/a/232246.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

短视频ai剪辑分发矩阵系统源码3年技术团队开发搭建打磨

如果您需要搭建这样的系统&#xff0c;建议您寻求专业的技术支持&#xff0c;以确保系统的稳定性和安全性。 在搭建短视频AI剪辑分发矩阵系统时&#xff0c;您需要考虑以下几个方面&#xff1a; 1. 技术实现&#xff1a;您需要选择适合您的需求和预算的技术栈&#xff0c;例如使…

STM32 配置TIM定时中断常用库函数

单片机学习&#xff01; 目录 ​编辑 1. 函数TIM_DeInit 2. 函数TIM_TimeBaseInit 配置时基单元 3. 函数TIM_TimeBaseStructInit 4. 函数TIM_Cmd 运行控制 5. 函数TIM_ITConfig 中断输出控制 6. 时基单元的时钟选择函数 6.1 函数TIM_InternalClockConfig 6.2 函数 TIM…

【图论笔记】克鲁斯卡尔算法(Kruskal)求最小生成树

【图论笔记】克鲁斯卡尔算法&#xff08;Kruskal&#xff09;求最小生成树 适用于 克鲁斯卡尔适合用来求边比较稀疏的图的最小生成树 简记&#xff1a; 将边按照升序排序&#xff0c;选取n-1条边&#xff0c;连通n个顶点。 添加一条边的时候&#xff0c;如何判断能不能添加…

python数据分析小案例:天猫订单数据综合分析

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 本数据集共收集了发生在一个月内的28010条数据&#xff0c;包含以下&#xff1a; 7个字段说明 订单编号&#xff1a;订单编号 总金额&#xff1a;订单总金额 买…

if语句和switch语句来确定金额之下的优惠折扣

一、优惠规则 输入相应的金额&#xff0c;可以获得规则之下&#xff0c;金额相应的享受的折扣&#xff0c;需要先定义金额&#xff0c;然后就是使用if语句进行判断&#xff0c;使用switch语句选择判断规则之下对应的优惠折扣。 二、相关代码 public class DiscountPrice {p…

Dockerfile文件

什么是dockerfile? Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像。 docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Docke…

ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders

1.关于稀疏卷积的解释&#xff1a;https://zhuanlan.zhihu.com/p/382365889 2. 答案&#xff1a; 在深度学习领域&#xff0c;尤其是计算机视觉任务中&#xff0c;遮蔽图像建模&#xff08;Masked Image Modeling, MIM&#xff09;是一种自监督学习策略&#xff0c;其基本思想…

rpc原理与应用

IPC和RPC&#xff1f; RPC 而RPC&#xff08;Remote Procedure Call&#xff09;&#xff0c;又叫做远程过程调用。它本身并不是一个具体的协议&#xff0c;而是一种调用方式。 gRPC 是 Google 最近公布的开源软件&#xff0c;基于最新的 HTTP2.0 协议&#xff0c;并支持常见…

【计算机网络】HTTPS协议原理

目录 一. HTTPS的基础概念 二. 概念准备 1. 密码学 2. 为什么要加密 三. 常见加密方式 1. 对称加密 2. 非对称加密 四. HTTPS原理探究 五. CA认证 1. 数据指纹&&数据摘要 2. 证书 3. 签名与验证 4. 琐碎知识点 5. 总结——完整流程 结束语 一. HTTPS的基…

开发猿的平平淡淡周末---2023/12/9

上周回顾 完成了遗留的开发任务&#xff0c;基本全部完成进一步了解了系统当时设计的原理熟悉了代码的重构 2023.12.9 天气晴 温度适宜 前言 小伙伴们大家好&#xff0c;时间很快&#xff0c;又来到了周末&#xff0c;也是一个平平淡淡的周末。上周只更了一篇博客...原…

交换机基本原理和配置

目录 一、数据链路层功能 二、交换机的工作原理 三、交换机的四大功能 一、数据链路层功能 位于网络层与物理层之间 数据链路的建立、维护与拆除帧包装、帧传输、帧同步帧的差错恢复流量控制 二、交换机的工作原理 交换机通过数据帧的源 MAC 地址&#xff0c;学习到交换机端…

讲座 | 颠覆传统摄像方式乃至计算机视觉的“脉冲视觉”

传统相机拍摄视频时其实是以一定帧率进行采样&#xff0c;视频其实还是一串图片的集合&#xff0c;因此低帧率时会觉得视频卡&#xff0c;拍摄高速运动物体时会有运动模糊等等问题。然而你能想象这一切都可以被“脉冲视觉”这一前沿技术改变吗&#xff1f; 今天下午听了北京大学…

数据库数据恢复—Mysql数据库误删表数据的数据恢复案例

mysql数据库数据恢复环境&#xff1a; 本地服务器&#xff0c;windows server操作系统 &#xff0c;部署有mysql单实例&#xff0c;数据库引擎类型为innodb&#xff0c;独立表空间&#xff0c;无数据库备份&#xff0c;未开启binlog。 mysql数据库故障&#xff1a; 工作人员使…

前端vue3——实现二次元人物拼图校验

文章目录 ⭐前言⭐vue3拖拽实现拼图&#x1f496; 思路分解&#x1f496; 布局结构&#x1f496; 拖拽函数&#x1f496; 校验函数&#x1f496; inscode整体代码 ⭐运行效果&#x1f496; 随机顺序&#x1f496; 拖拽中&#x1f496; 校验失败&#x1f496; 校验通过 ⭐总结⭐…

2.2 网络多线程(私聊、群发、发送文件、推送新闻、离线留言)

文章目录 一、私聊1.1 分析1.2 客户端1.2.1 MessageClientService 私聊类1.2.2 ClientConnectServerThread 线程类 1.3 服务端1.3.1 ServerConnectClientThread 线程类 1.4功能演示 二、群发消息2.1 分析2.2 客户端2.2.1 MessageClientService类2.2.2 ClientConnectServerThrea…

使用Microsoft Dynamics AX 2012 - 6. 运营规划

运营规划的主要职责是确保项目在需要的时候可用&#xff0c;同时达到高经济效益的目标。运营规划必须解决高供应准备度和低库存这两个相互冲突的优先事项。 运营规划中的业务流程 在Dynamics AX中&#xff0c;长期预测和短期总体规划由运营规划模块&#xff08;“总体规划”&…

面试计算机网络八股文五问五答第一期

面试计算机网络八股文五问五答第一期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1.TCP和UDP的区别 TCP和UDP是两种网络传输协议&#xff0c;它们的主要区别在…

Android audio环形缓冲队列

1、背景 在学习audio的过程中&#xff0c;看到了大神zyuanyun的博客&#xff0c;在博客的结尾&#xff0c;大神留下了这些问题&#xff1a; 但是大神没有出后续的博文来说明audio环形缓冲队列的具体实现&#xff0c;这勾起了我强烈的好奇心。经过一段时间的走读代码&#xff…

Docker Network(网络)——8

目录&#xff1a; Docker 为什么需要网络管理Docker 网络架构简介 CNMLibnetwork驱动常见网络类型 bridge 网络host 网络container 网络none 网络overlay 网络docker 网络管理命令 docker network createdocker network inspectdocker network connectdocker network disconne…

22、文件上传漏洞——文件上传检测与绕过

文章目录 一、文件上传漏洞原理二、客户端检测及绕过&#xff08;JS检测与绕过&#xff09;三、服务端检测3.1 后缀名检测与绕过3.2 MIME类型检测与绕过3.3 文件内容检测与绕过3.4 00截断检测与绕过3.5 条件竞争检测与绕过 一、文件上传漏洞原理 上传文件时&#xff0c;如果服务…
最新文章