【算法与数据结构】37、LeetCode解数独

文章目录

  • 一、题目
  • 二、解法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

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

二、解法

  思路分析:本题也是一道困难题,难点在于如何构建数独棋盘,如何检查棋盘的合法性,再一个难点在于如何对棋盘进行遍历并放置数字。数组棋盘的构建笔者采用了一个最朴素的方法,将已知的‘.’和数字依次push_back进棋盘数组中;然后根据数独的规则,每行每列,每个九空格内不能有重复的元素,构建isValid函数;然后利用两层嵌套循环遍历棋盘,棋盘的每个点用1-9的数组依次带入,如果合法则进行下一步的递归。最终得到一个数独的解,这个解就是整个棋盘数组,将其输出。
  程序如下

class Solution {
private:
    bool isValid(vector<vector<char>>& board, char num, int row, int col) {   // 检查棋盘是否合法   
        // 检查行列,九空格内是否有重复元素
        for (int i = 0; i < board.size(); i++) {    // 检查列
            if (board[i][col] == num) return false;
        }
        for (int j = 0; j < board[0].size(); j++) {    // 检查行
            if (board[row][j] == num) return false;
        }
        // 检查九空格,找到board[row][col]所在的九空格, 然后用二层循环遍历
        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] == num) return false;
            }
        }
        return true;
    }
    bool backtracking(vector<vector<char>>& board) {
        for (int row = 0; row < board.size(); row++) {
            for (int col = 0; col < board[0].size(); col++) {
                if (board[row][col] != '.') continue;
                for (char num = '1'; num <= '9'; num++) {
                    if (isValid(board, num, row, col)) {
                        board[row][col] = num; // 放置数字,处理节点;
                        if(backtracking(board)) return true;   // 递归
                        board[row][col] = '.'; // 回溯,撤销处理结果
                    }
                }
                return false;   // 九个数字都不行,说明数独无解
            }
        }
        return true;
    }
public:
    vector<vector<char>> solveSudoku(vector<vector<char>>& board) {
        backtracking(board);
        return board;
    }
};

复杂度分析:

  • 时间复杂度: O ( n ! ) O(n!) O(n!)
  • 空间复杂度: O ( n ) O(n) O(n)

三、完整代码

# include <iostream>
# include <vector>
# include <string>
using namespace std;

class Solution {
private:
    bool isValid(vector<vector<char>>& board, char num, int row, int col) {   // 检查棋盘是否合法   
        // 检查行列,九空格内是否有重复元素
        for (int i = 0; i < board.size(); i++) {    // 检查列
            if (board[i][col] == num) return false;
        }
        for (int j = 0; j < board[0].size(); j++) {    // 检查行
            if (board[row][j] == num) return false;
        }
        // 检查九空格,找到board[row][col]所在的九空格, 然后用二层循环遍历
        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] == num) return false;
            }
        }
        return true;
    }
    bool backtracking(vector<vector<char>>& board) {
        for (int row = 0; row < board.size(); row++) {
            for (int col = 0; col < board[0].size(); col++) {
                if (board[row][col] != '.') continue;
                for (char num = '1'; num <= '9'; num++) {
                    if (isValid(board, num, row, col)) {
                        board[row][col] = num; // 放置数字,处理节点;
                        if(backtracking(board)) return true;   // 递归
                        board[row][col] = '.'; // 回溯,撤销处理结果
                    }
                }
                return false;   // 九个数字都不行,说明数独无解
            }
        }
        return true;
    }
public:
    vector<vector<char>> solveSudoku(vector<vector<char>>& board) {
        backtracking(board);
        return board;
    }
};

int main() {
    vector<vector<char>> board;
    board.push_back({ '5', '3', '.', '.', '7', '.', '.', '.', '.' });
    board.push_back({ '6', '.', '.', '1', '9', '5', '.', '.', '.' });
    board.push_back({ '.', '9', '8', '.', '.', '.', '.', '6', '.' });
    board.push_back({ '8', '.', '.', '.', '6', '.', '.', '.', '3' });
    board.push_back({ '4', '.', '.', '8', '.', '3', '.', '.', '1' });
    board.push_back({ '7', '.', '.', '.', '2', '.', '.', '.', '6' });
    board.push_back({ '.', '6', '.', '.', '.', '.', '2', '8', '.' });
    board.push_back({ '.', '.', '.', '4', '1', '9', '.', '.', '5' });
    board.push_back({ '.', '.', '.', '.', '8', '.', '.', '7', '9' });
    Solution s1;
    vector<vector<char>> result = s1.solveSudoku(board);
    for (vector<vector<char>>::iterator it = result.begin(); it != result.end(); it++) {
        for (vector<char>::iterator jt = (*it).begin(); jt != (*it).end(); jt++) {
            cout << *jt << " ";
        }
        cout << endl;
    }
    system("pause");
    return 0;
}

end

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

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

相关文章

Halcon一维码识别

文章目录 参数连接halcon 自带案例1&#xff08;设置校验位识别条码&#xff09;Halcon 自带案例2&#xff08;设置对比度识别条码&#xff09;Halcon 自带案例3&#xff08;存在曲面变形&#xff09;Halcon 自带案例4&#xff08;设置条码扫描线&#xff09;Halcon 自带案例5&…

Linux---Ubuntu操作系统

1. Ubuntu操作系统的介绍 Ubuntu操作系统是属于Linux操作系统中的一种&#xff0c;它是免费、稳定又可以拥有绚丽界面的一个操作系统 2. Ubuntu图形界面的介绍 任务栏 窗口操作按钮 窗口菜单条 任务栏效果图: 窗口操作按钮效果图: 窗口菜单条效果图: 3. 与Windows目录结…

『C++成长记』拷贝构造函数

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;C &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、拷贝构造函数 &#x1f4d2;1.1拷贝构造函数的概念 &#x1f4d2;1.2拷贝构造…

Java项目-瑞吉外卖Day6

导入用户地址功能&#xff0c;为用户添加地址&#xff1a; 添加AddressBook实体类&#xff0c;创建相关service&#xff0c;mapper&#xff0c;serviceImpl&#xff0c;controller类。 controller类直接使用的资料提供的代码。 实现菜品展示移动端开发&#xff1a; 看到前端发…

添加,更换和删除 vSphere License

目录 1. 删除 License2. 添加 License&#xff08;1&#xff09;输入许可证密钥&#xff08;2&#xff09;编辑许可证名称&#xff08;3&#xff09;确认许可证信息 3. 分配/更换 License&#xff08;1&#xff09;为 vCenter Server 分配 License&#xff08;2&#xff09;为 …

Android : 序列化 Parcelable 简单应用

1.Parcelable 介绍 Parcelable 是 Android 提供的一个序列化接口&#xff0c;用于将数据写入 Parcel&#xff0c;以及从 Parcel 中读取数据。一个类只要实现了这个接口&#xff0c;该类的对象就可以被序列化&#xff0c;主要用于 IPC&#xff08;进程间通信&#xff09;、Bind…

产品经理之如何编写竞品分析(医疗HIS系统管理详细案例模板)

目录 一.项目周期 二.竞品分析的目的 三.竞品分析包含的维度 四.如何选择竞品 五.竞品画布 六.案例模板 一.项目周期 在整个项目的周期&#xff0c;产品经理所做的事情主要在项目前期做市场分析、需求调研等&#xff0c;下面一张图概况了整个项目周期产品经理、开发工程师…

网络安全——Iptables防DDoS攻击实验

一、实验目的要求&#xff1a; 二、实验设备与环境&#xff1a; 三、实验原理&#xff1a; 四、实验步骤&#xff1a; 五、实验现象、结果记录及整理&#xff1a; 六、分析讨论与思考题解答&#xff1a; 一、实验目的要求&#xff1a; 1、掌握常见DDoS攻击SYN Flood的攻击…

gdb本地调试版本移植至ARM-Linux系统

移植ncurses库 本文使用的ncurses版本为ncurses-5.9.tar.gz 下载地址&#xff1a;https://ftp.gnu.org/gnu/ncurses/ncurses-5.9.tar.gz 1. 将ncurses压缩包拷贝至Linux主机或使用wget命令下载并解压 tar-zxvf ncurses-5.9.tar.gz 2. 解压后进入到ncurses-5.9目录…

解决员工安全隐患的终极方案!迅软DSE答疑员工终端安全管控策略揭秘!

企业终端安全管控对于企事业单位来说至关重要。迅软DSE终端安全系统提供了丰富的终端安全桌面管理策略&#xff0c;可以对终端用户的上网行为和终端操作行为进行管理和控制&#xff0c;从而实现桌面终端的标准化管理&#xff0c;解决终端安全管理问题&#xff0c;并提高员工工作…

阿里云SLB的使用总结

一、什么是SLB 实现k8s的服务service的一种推荐方式&#xff0c;也是服务上云后&#xff0c;替代LVS的一个必选产品。 那么它有什么作用呢&#xff1f; 1、负载均衡&#xff0c;是它与生俱来的。可以配置多个服务器组&#xff1a;包括虚拟服务器组、默认服务器组、主备服务器…

小程序使用Nodejs作为服务端,Nodejs与与MYSQL数据库相连

小程序使用Nodejs作为服务端,Nodejs与与MYSQL数据库相连 一、搭建环境二、配置Nodejs三、与小程序交互四、跨域处理/报错处理五、nodejs连接mysql数据库六、微信小程序连接nodejs报错七、小程序成功与服务端相连,且能操作数据库一、搭建环境 新建空文件夹:Win + R进入cmd命令…

C++STL的list模拟实现

文章目录 前言 list实现push_back迭代器(重点)普通迭代器const迭代器 inserterase析构函数构造函数拷贝构造赋值 vector和list的区别 前言 要实现STL的list, 首先我们还得看一下list的源码。 我们看到这么一个东西&#xff0c;我们知道C兼容C&#xff0c;可以用struct来创建一…

Quartus II + Modelsim 脚本仿真

软件版本&#xff1a;Intel Quartus Prime Design Suite: 23.2 方式参考附件Intel 官方文档&#xff1a;Questa*-Intel FPGA Edition Quick-Start: Intel Quartus Prime Pro Edition 第1步&#xff0c;创建一个ram ip&#xff0c;并形成一个例化的top层ip 第2步&#xff0c;自…

独立完成软件的功能的测试(2)

独立完成软件的功能的测试&#xff08;2&#xff09; &#xff08;12.13&#xff09; 1. 对穷举场景设计测试点&#xff08;等价类划分法&#xff09; 等价类划分法的概念&#xff1a; 说明&#xff1a;数据有共同特征&#xff0c;成功失败分类&#xff1a; 有效&#xff1a…

FPGA使用乘法的方式

FPGA使用乘法的方式 方法一:直接使用乘法符“*” 源代码 module multiply(input [7:0] a,input [7:0] b,output wire [15:0] result);(*use_dsp48 = "yes"*) wire [15:0] result;assign result = a*b; endmodule仿真代码 module multiply_tb();reg [7:0] a; re…

大象慧云:从设立分部到迁移总部 与贵阳贵安共筑税务数字化未来

近年来&#xff0c;贵阳贵安着力提升政务服务水平&#xff0c;通过擦亮“贵人服务”品牌&#xff0c;持续优化营商环境。在这样的环境下&#xff0c;再加上“大数据基因”&#xff0c;对于希望在大数据领域大展拳脚的企业来说&#xff0c;贵阳贵安无疑成为了一个极具吸引力的选…

MySQL笔记-第11章_数据处理之增删改

视频链接&#xff1a;【MySQL数据库入门到大牛&#xff0c;mysql安装到优化&#xff0c;百科全书级&#xff0c;全网天花板】 文章目录 第11章_数据处理之增删改1. 插入数据1.1 实际问题1.2 方式1&#xff1a;VALUES的方式添加1.3 方式2&#xff1a;将查询结果插入到表中 2. 更…

C语言—每日选择题—Day46

第一题 1. 下列程序段的输出结果是&#xff08;&#xff09; #include <stdio.h> int main() {int x 1,a 0,b 0;switch(x) {case 0: b;case 1: a;case 2: a;b;}printf("a%d,b%d\n", a, b);return 0; } A&#xff1a;a2,b1 B&#xff1a;a1,b1 C&#xf…

CGAL的3D Alpha Wrapping

1、介绍 几何建模和处理中的各种任务都需要将三维对象表示为有效的曲面网格&#xff0c;其中“有效”指的是不透水、无交叉、可定向和2流形的网格。这样的表示提供了内部/外部和测地线邻域的定义良好的概念。 3D数据通常是通过测量和重建获得的&#xff0c;由人类设计&#xff…