【LeetCode算法系列题解】第36~40题

news2024/11/18 4:17:53

CONTENTS

    • LeetCode 36. 有效的数独(中等)
    • LeetCode 37. 解数独(困难)
    • LeetCode 38. 外观数列(中等)
    • LeetCode 39. 组合总和(中等)

LeetCode 36. 有效的数独(中等)

【题目描述】

请你判断一个 9 x 9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

  • 数字 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"]]
输出:true

【示例2】

输入:board = 
[["8","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"]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

【提示】

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
board[i][j] 是一位数字(1-9)或者 '.'

【分析】


直接按题意模拟即可。


【代码】

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        bool st[10];
        for (int i = 0; i < 9; i++)
        {
            memset(st, false, sizeof st);
            for (int j = 0; j < 9; j++)
                if (board[i][j] == '.') continue;
                else if (st[board[i][j] - '0']) return false;
                else st[board[i][j] - '0'] = true;
        }
        for (int i = 0; i < 9; i++)
        {
            memset(st, false, sizeof st);
            for (int j = 0; j < 9; j++)
                if (board[j][i] == '.') continue;
                else if (st[board[j][i] - '0']) return false;
                else st[board[j][i] - '0'] = true;
        }
        for (int i = 0; i < 9; i += 3)  // 枚举每个3*3方格的左上角坐标
            for (int j = 0; j < 9; j += 3)
            {
                memset(st, false, sizeof st);
                for (int x = i; x < i + 3; x++)  // 枚举每个3*3方格中每个点的坐标
                    for (int y = j; y < j + 3; y++)
                        if (board[x][y] == '.') continue;
                        else if (st[board[x][y] - '0']) return false;
                        else st[board[x][y] - '0'] = true;
            }
        return true;
    }
};

LeetCode 37. 解数独(困难)

【题目描述】

编写一个程序,通过填充空格来解决数独问题。
数独的解法需遵循如下规则:

  • 数字 1-9 在每一行只能出现一次。
  • 数字 1-9 在每一列只能出现一次。
  • 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次(请参考示例图)。

数独部分空格内已填入了数字,空白格用 '.' 表示。

【示例1】

在这里插入图片描述

输入:board = 
输入: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"]]

【提示】

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
board[i][j] 是一位数字(1-9)或者 '.'
题目数据保证输入数独仅有一个解

【分析】


类似 N 皇后问题,爆搜每个位置可以填入的数,我们需要使用三个数组:row[i][x]col[i][x]cell[i][j][x],分别表示第 i i i 行(列)是否已经存在数字 x x x 以及第 i , j i,j i,j(左上角坐标)个3*3小方格是否已经存在数字 x x x


【代码】

class Solution {
public:
    bool row[9][9], col[9][9], cell[3][3][9];

    void solveSudoku(vector<vector<char>>& board) {
        memset(row, false, sizeof row);
        memset(col, false, sizeof col);
        memset(cell, false, sizeof cell);
        for (int i = 0; i < 9; i++)
            for (int j = 0; j < 9; j++)
                if (board[i][j] == '.') continue;
                else
                {
                    int t = board[i][j] - '1';  // 将'1'-'9'映射为0-8
                    row[i][t] = col[j][t] = cell[i / 3][j / 3][t] = true;
                }
        dfs(board, 0, 0);  // 从第0行第0列开始搜索
    }

    bool dfs(vector<vector<char>>& board, int x, int y)
    {
        if (x == 9) return true;  // 搜完了所有位置,找到解
        if (y == 9) return dfs(board, x + 1, 0);  // 搜完了一行,x加一y清零
        if (board[x][y] != '.') return dfs(board, x, y + 1);  // 该位置已经有数直接跳过
        for (int i = 0; i < 9; i++)
            if (!row[x][i] && !col[y][i] && !cell[x / 3][y / 3][i])
            {
                board[x][y] = i + '1';
                row[x][i] = col[y][i] = cell[x / 3][y / 3][i] = true;
                if (dfs(board, x, y + 1)) return true;  // 注意不能写return dfs(board, x, y + 1);
                board[x][y] = '.';  // 还原现场
                row[x][i] = col[y][i] = cell[x / 3][y / 3][i] = false;
            }
        return false;  // 该位置已经用完了所有数,返回false
    }
};

LeetCode 38. 外观数列(中等)

【题目描述】

给定一个正整数 n,输出外观数列的第 n 项。
外观数列是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。
你可以将其视作是由递归公式定义的数字字符串序列:

  • countAndSay(1) = "1"
  • countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。

前五项如下:

1.     1
2.     11
3.     21
4.     1211
5.     111221
第一项是数字 1 
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"

描述一个数字字符串,首先要将字符串分割为最小数量的组,每个组都由连续的最多相同字符组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。

例如,数字字符串 "3322251" 的描述如下图:

在这里插入图片描述

【示例1】

输入:n = 1
输出:"1"
解释:这是一个基本样例。

【示例2】

输入:n = 4
输出:"1211"
解释:
countAndSay(1) = "1"
countAndSay(2) = 读 "1" = 一 个 1 = "11"
countAndSay(3) = 读 "11" = 二 个 1 = "21"
countAndSay(4) = 读 "21" = 一 个 2 + 一 个 1 = "12" + "11" = "1211"

【提示】

1 ≤ n ≤ 30 1\le n\le 30 1n30

【分析】


直接按题意模拟即可。


【代码】

class Solution {
public:
    string countAndSay(int n) {
        string s = "1";  // 初始化
        for (int i = 0; i < n - 1; i++)  // 需要变换n-1次
        {
            string t;
            for (int j = 0, k; j < s.size(); j = k)
            {
                k = j + 1;
                while (k < s.size() && s[k] == s[k - 1]) k++;  // 找到第一个不同的数
                t += to_string(k - j) + s[j];  // 一共k-j个s[j]
            }
            s = t;
        }
        return s;
    }
};

LeetCode 39. 组合总和(中等)

【题目描述】

给你一个无重复元素的整数数组 candidates 和一个目标整数 target,找出 candidates 中可以使数字和为目标数 target所有不同组合 ,并以列表形式返回。你可以按任意顺序返回这些组合。
candidates 中的同一个数字可以无限制重复被选取。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。

【示例1】

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

【示例2】

输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

【示例3】

输入: candidates = [2], target = 1
输出: []

【提示】

1 ≤ c a n d i d a t e s . l e n g t h ≤ 30 1\le candidates.length\le 30 1candidates.length30
2 ≤ c a n d i d a t e s [ i ] ≤ 40 2\le candidates[i]\le 40 2candidates[i]40
candidates 的所有元素互不相同
1 ≤ t a r g e t ≤ 40 1\le target\le 40 1target40

【分析】


本题要求出所有的方案,因此考虑可以使用爆搜。枚举每个数选不同的数量,若当前组合方案的和超过 target 了则直接剪枝。此外,由于相同的组合调换顺序不属于新的组合,因此爆搜的时候还需要保证顺序关系保证一种组合固定以一种顺序出现一次,而不会重复。


【代码】

class Solution {
public:
    vector<vector<int>> res;
    vector<int> v;

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        dfs(candidates, 0, target);
        return res;
    }

    // now表示从第几个数开始选,因为序列不能重复,例如[2,2,3]和[2,3,2]是一样的
    // target每次减去选中的数,减为0说明找到和恰好为target的序列
    void dfs(vector<int>& c, int now, int target)
    {
        if (target <= 0)  // 剪枝
        {
            if (target == 0) res.push_back(v);  // 找到一个合法序列
            return;
        }
        for (int i = now; i < c.size(); i++)  // 每次dfs都可以选一次now
        {
            v.push_back(c[i]);
            dfs(c, i, target - c[i]);
            v.pop_back();  // 还原现场
        }
    }
};

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

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

相关文章

钡铼R40边缘计算网关与华为云合作,促进物联网传感器数据共享与应用

场景说明 微型气象是不可预测的&#xff0c;基本上不能通过人工手段来分析其变化&#xff0c;因此必须运用新技术&#xff0c;对气象进行实时监测&#xff0c;以便采取相应的措施来避免或解决事故的发生。而常规气象环境数据采集容易造成数据损失、人力成本高、数据安全性差、…

【数据分享】2023年7月道路数据(全国/分省/分城市/无需转发)

道路数据是我们在各项研究中经常使用的数据&#xff01;道路数据虽然很常用&#xff0c;但是却基本没有能下载最近年份道路数据的网站&#xff0c;所以很多人不知道如何获到道路数据。 本次我们为大家推荐的下载道路数据的网站是Open Street Map&#xff01;我们先来了解下Ope…

查漏补缺 - JS三 WebAPI

目录 BOMhistory DOM操作DOM1&#xff0c;dom.children 和 dom.childNodes 区别2&#xff0c;dom.remove()3&#xff0c;其他常用 API DOM 属性1&#xff0c;标准属性2&#xff0c;自定义属性 DOM 内容DOM样式DOM事件 JavaScript 包括 EcmaScript 和 WebAPI EcmaScript 包括 语…

03Linux

物联201白悦颖 学号&#xff1a;2008070101 青岛科技大学 目录 ⼀、进程与线程 1. 进程 2. 线程 3. 进程和线程的使用情况 ⼆、linux下的sudo命令 1. sudo 功能&#xff1f; sudo提供的临时权限什么时候被取消&#xff1f; 为什么要取消 sudo 权限…

C++之访问vector<vector<char>>中的vector<char>元素(一百八十七)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

ceph架构及 IO流程

CEPH是由多个节点构成的集群&#xff0c;它具有良好的可扩展性和可靠性。节点之间相互通信以达到&#xff1a; 存储和检索数据 数据复制 监控集群的健康状况 保证数据的完整性 检测故障并恢复 基本架构如下图&#xff1a; 分布式对象存储系统RADOS是CEPH最为关键的技术&a…

深入理解css3背景图边框

border-image知识点 重点理解 border-image-slice 设置的值将边框背景图分为9份&#xff0c;图像中间的舍弃&#xff0c;其他部分图像对应边框的相应区域放置&#xff0c;上右下左四角固定&#xff0c;border-image-repeat设置的是除四角外其他部分的显示方式。 截图来自菜鸟教…

2分钟搭建FastGPT训练企业知识库AI助理(Docker部署)

我们使用宝塔面板来进行搭建&#xff0c;更方便快捷灵活&#xff0c;争取操作时间只需两分钟 宝塔面板下安装Docker 在【软件商店中】安装【docker管理器】【docker模块】即可 通过Docker安装FastGPT 通过【Docker】【添加容器】【容器编排】创建里新增docker-compose.yaml以下…

部署项目至服务器

安装conda https://zhuanlan.zhihu.com/p/489499097 个人租借的服务器如何进行端口的开放呢&#xff1f; 防火墙设置&#xff1a; 添加规则设置&#xff1a; 即可&#xff1b; 通常下租借的服务器没有防火墙设置 相关链接&#xff1a; https://blog.csdn.net/weixin_4520…

Vulnhub内网渗透DC-7靶场通关

个人博客: xzajyjs.cn DC系列共9个靶场&#xff0c;本次来试玩一下一个 DC-7&#xff0c;下载地址。 下载下来后是 .ova 格式&#xff0c;建议使用vitualbox进行搭建&#xff0c;vmware可能存在兼容性问题。靶场推荐使用NAT(共享)模式&#xff0c;桥接模式可能会造成目标过多不…

ARM DIY(六)音频调试

前言 今天&#xff0c;调试一下音频 硬件焊接 硬件部分核心是 LM4871 音频功放芯片 对于 SOC 来讲很简单&#xff0c;就一个引脚 HPOUTL&#xff08;单声道&#xff09;&#xff1b;对于扬声器来讲也很简单&#xff0c;就两个引脚&#xff0c;插上就可以了。 另外一个关键点…

Revit SDK:SpatialFieldGradient 在面上显示渐变颜色(AVF)分析显示样式

前言 这个例子使用Revit显示样式功能将面显示成不同的颜色。分析显示样式参考官方文档。 内容 效果&#xff1a; 核心逻辑&#xff1a; 得到一个 SpatialFieldManager拾取一系列的面&#xff1a;uiDoc.Selection.PickObjects(ObjectType.Face)计算面上的 UV 值&#xff0c;…

Ubuntu22.04.1上 mosquitto安装及mosquitto-auth-plug 认证插件配置

Ubuntu22.04.1上 mosquitto安装及mosquitto-auth-plug 认证插件配置 1、先上效果&#xff0c;可以根据mysql中mosquitto数据库的不同users角色登陆mosquitto&#xff1a; SELECT * FROM mosquitto.users; id,username,pw,super 1,jjolie,PBKDF2$sha256$901$yZnELWKK4NnaNNJl…

使用SpaceDesk连接平板作为电脑副屏详细步骤教程

文章目录 下载安装PC端安装安卓端安装 配置步骤PC端安卓端 连接 SpaceDesk官网链接https://www.spacedesk.net/ (应该是需要科学上网才能进入) SpaceDesk它可以连接安卓,苹果的平板,手机等&#xff0c;也可以连接其他可以打开网页&#xff08;HTML5&#xff09;的设备。 这里我…

【大数据模型】让chatgpt为开发增速(开发专用提示词)

汝之观览&#xff0c;吾之幸也&#xff01;本文主要聊聊怎样才能更好的使用提示词&#xff0c;给开发提速&#xff0c;大大缩减我们的开发时间&#xff0c;比如在开发中使用生成表结构脚本的提示词&#xff0c;生成代码的提示词等等。 一、准备 本文主要根据Claude进行演示&am…

Python正则表达式中re.sub自定义替换方法正确使用方法

大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 话不多说&#xff0c;直接开搞&#xff0c;如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 在使用正则替换时&#xff0c;有时候需要将匹配的结果做对应处理&#xff0c;便可以使用自定义替换方法。 re.sub的用法为&…

ES线程池设置

一文搞懂ES中的线程池 - 知乎 ES线程池设置-阿里云开发者社区 文章目录 一、简介 二、线程池类型 2.1、fixed 2.2、scaling 2.3、direct 2.4、fixed_auto_queue_size 三、处理器设置 四、查看线程池 4.1、cat thread pool 4.2、nodes info 4.3、nodes stats 4.4、no…

【C++初阶】模拟实现优先级队列priority_queue

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

Elasticsearch:将段落向量搜索添加到 Lucene

作者&#xff1a;Benjamin Trent 向量搜索是信息检索工具箱中的一个强大工具。 将向量与词法搜索&#xff08;如 BM25&#xff09;一起使用很快变得司空见惯。 但向量搜索中仍然存在一些痛点需要解决。 主要的一个是文本嵌入模型和处理更大的文本输入。 像 BM25 这样的词法搜索…