【综合算法学习】(第十三篇)

目录

解数独(hard)

题目解析

讲解算法原理

编写代码

单词搜索(medium)

题目解析

解析算法原理

编写代码


解数独(hard)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

编写⼀个程序,通过填充空格来解决数独问题。
数独的解法需遵循如下规则:
数字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"]]
输出:[["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]是⼀位数字或者'.'题⽬数据保证输⼊数独仅有⼀个解

讲解算法原理

解法:算法思路:

为了存储每个位置的元素,我们需要定义⼀个⼆维数组。⾸先,我们记录所有已知的数据,然后遍历所有需要处理的位置,并遍历数字1~9。对于每个位置,我们检查该数字是否可以存放在该位置,同时检查⾏、列和九宫格是否唯⼀。
我们可以使⽤⼀个⼆维数组来记录每个数字在每⼀⾏中是否出现,⼀个⼆维数组来记录每个数字在每⼀列中是否出现。对于九宫格,我们可以以⾏和列除以3得到的商作为九宫格的坐标,并使⽤⼀个三维数组来记录每个数字在每⼀个九宫格中是否出现。在检查是否存在冲突时,只需检查⾏、列和九宫格⾥对应的数字是否已被标记。如果数字⾄少有⼀个位置(⾏、列、九宫格)被标记,则存在冲突,因此不能在该位置放置当前数字。
• 特别地,在本题中,我们需要直接修改给出的数组,因此在找到⼀种可⾏的⽅法时,应该停⽌递
归,以防⽌正确的⽅法被覆盖。
初始化定义:
1. 定义⾏、列、九宫格标记数组以及找到可⾏⽅法的标记变量,将它们初始化为false。

2. 定义⼀个数组来存储每个需要处理的位置。
3. 将题⽬给出的所有元素的⾏、列以及九宫格坐标标记为true。4. 将所有需要处理的位置存⼊数组。
递归函数设计:voiddfs(vector<vector<char>>&board,intpos)参数:pos(当前需要处理的坐标);
返回值:⽆;
函数作⽤:在当前坐标填⼊合适数字,查找数独答案。
递归流程如下:
1. 结束条件:已经处理完所有需要处理的元素。如果找到了可⾏的解决⽅案,则将标记变量更新为true并返回。
2. 获取当前需要处理的元素的⾏列值。
3. 遍历数字1~9。如果当前数字可以填⼊当前位置,并且标记变量未被赋值为true,则将当前位置的⾏、列以及九宫格坐标标记为true,将当前数字赋值给board数组中的相应位置元素,然后对下⼀个位置进⾏递归。
4. 递归结束时,撤回标记。

编写代码

c++算法代码:

class Solution
{bool row[9][10], col[9][10], grid[3][3][10];
public:void solveSudoku(vector<vector<char>>& board) {// 初始化for(int i = 0; i < 9; i++){for(int j = 0; j < 9; j++){if(board[i][j] != '.'){int num = board[i][j] - '0';row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = true;}}}dfs(board);}bool dfs(vector<vector<char>>& board){for(int i = 0; i < 9; i++){for(int j = 0; j < 9; j++){if(board[i][j] == '.'){// 填数for(int num = 1; num <= 9; num++){if(!row[i][num] && !col[j][num] && !grid[i / 3][j / 3]
[num]){board[i][j] = '0' + num;row[i][num] = col[j][num] = grid[i / 3][j / 3]
[num] = true;if(dfs(board) == true) return true; // 重点理解 // 恢复现场board[i][j] = '.';row[i][num] = col[j][num] = grid[i / 3][j / 3]
[num] = false;}}return false; // 重点理解}}}return true; // 重点理解}
};

java算法代码:

class Solution
{boolean[][] row, col;boolean[][][] grid;public void solveSudoku(char[][] board) {row = new boolean[9][10];col = new boolean[9][10];grid = new boolean[3][3][10];// 初始化for(int i = 0; i < 9; i++)for(int j = 0; j < 9; j++)if(board[i][j] != '.'){int num = board[i][j] - '0';row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = true;}dfs(board);}public boolean dfs(char[][] board){for(int i = 0; i < 9; i++){for(int j = 0; j < 9; j++){if(board[i][j] == '.'){// 填数for(int num = 1; num <= 9; num++){// 剪枝if(!row[i][num] && !col[j][num] && !grid[i / 3][j / 3]
[num]){board[i][j] = (char)('0' + num);row[i][num] = col[j][num] = grid[i / 3][j / 3]
[num] = true;if(dfs(board) == true) return true; // 重点理解 // 恢复现场board[i][j] = '.';row[i][num] = col[j][num] = grid[i / 3][j / 3]
[num] = false;}}return false; // 重点理解}}}return true; // 重点理解}
}

单词搜索(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给定⼀个mxn⼆维字符⽹格board和⼀个字符串单词word。如果word存在于⽹格中,返回true;否则,返回false。
单词必须按照字⺟顺序,通过相邻的单元格内的字⺟构成,其中“相邻”单元格是那些⽔平相邻或垂直相邻的单元格。同⼀个单元格内的字⺟不允许被重复使⽤。
• ⽰例1:


输⼊:board=[["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]],word="ABCCED"输出:true
• ⽰例2:


输⼊:board=[["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]],word="SEE"输出:true
• ⽰例3:


输⼊:board=[["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]],word="ABCB"
输出:false
• 提⽰:
m==board.length
n=board[i].length
1<=m,n<=6
1<=word.length<=15
board和word仅由⼤⼩写英⽂字⺟组成

解析算法原理

解法:算法思路:

我们需要假设每个位置的元素作为第⼀个字⺟,然后向相邻的四个⽅向进⾏递归,并且不能出现重复使⽤同⼀个位置的元素。通过深度优先搜索的⽅式,不断地枚举相邻元素作为下⼀个字⺟出现的可能性,并在递归结束时回溯,直到枚举完所有可能性,得到正确的结果。
递归函数设计:booldfs(intx,inty,intstep,vector<vector<char>>&board,stringword,vector<vector<bool>>&vis,int&n,int&m,int&len)
参数:x(当前需要进⾏处理的元素横坐标),y(当前需要进⾏处理的元素横坐标),step(当前已经处理的元素个数),word(当前的字符串状态);
返回值:当前坐标元素作为字符串中下标step的元素出现是否可以找到成⽴的字符串。

函数作⽤:判断当前坐标的元素作为字符串中下标step的元素出现时,向四个⽅向传递,查找是否存在路径结果与字符串相同。
递归函数流程:

1. 遍历每个位置,标记当前位置并将当前位置的字⺟作为⾸字⺟进⾏递归,并且在回溯时撤回标记。

2. 在每个递归的状态中,我们维护⼀个步数step,表⽰当前已经处理了⼏个字⺟。
◦ 若当前位置的字⺟与字符串中的第step个字⺟不相等,则返回false。◦ 若当前step的值与字符串⻓度相等,表⽰存在⼀种路径使得word成⽴,返回true。
3. 对当前位置的上下左右四个相邻位置进⾏递归,若递归结果为true,则返回true。

4. 若相邻的四个位置的递归结果都为false,则返回false。
• 特别地,如果使⽤将当前遍历到的字符赋值为空格,并在回溯时恢复为原来的字⺟的⽅法,则在递归时不会重复遍历当前元素,可达到不使⽤标记数组的⽬的。

编写代码

c++算法代码:

class Solution
{bool vis[7][7];int m, n;
public:bool exist(vector<vector<char>>& board, string word) {m = board.size(), n = board[0].size();for(int i = 0; i < m; i++)for(int j = 0; j < n; j++){if(board[i][j] == word[0]){vis[i][j] = true;if(dfs(board, i, j, word, 1)) return true;vis[i][j] = false;}}return false;}int dx[4] = {0, 0, -1, 1};int dy[4] = {1, -1, 0, 0};bool dfs(vector<vector<char>>& board, int i, int j, string& word, int pos){if(pos == word.size()) return true;// 向量的⽅式,定义上下左右四个位置for(int k = 0; k < 4; k++){int x = i + dx[k], y = j + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && board[x][y] 
== word[pos]){vis[x][y] = true;if(dfs(board, x, y, word, pos + 1)) return true;vis[x][y] = false;}}return false;}
};

java算法代码:

class Solution
{boolean[][] vis;int m, n;char[] word;public boolean exist(char[][] board, String _word) {m = board.length; n = board[0].length;word = _word.toCharArray();vis = new boolean[m][n];for(int i = 0; i < m; i++)for(int j = 0; j < n; j++){if(board[i][j] == word[0]){vis[i][j] = true;if(dfs(board, i, j, 1)) return true;vis[i][j] = false;}}return false;}int[] dx = {0, 0, 1, -1};int[] dy = {1, -1, 0, 0};public boolean dfs(char[][] board, int i, int j, int pos){if(pos == word.length){return true;}// 上下左右去匹配 word[pos]// 利⽤向量数组,⼀个 for 搞定上下左右四个⽅向for(int k = 0; k < 4; k++){int x = i + dx[k], y = j + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && board[x][y] 
== word[pos]){vis[x][y] = true;if(dfs(board, x, y, pos + 1)) return true;vis[x][y] = false;}}return false;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】string 类模拟实现:深入探索字符串操作原理

快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f6a9;在之前的文章中我们学会了对string类函数的使用&#xff0c;现在让我们对其进行模拟实现吧~&#x1f6a9; 目录 &#x1f4af;引言 &#x1f4…

[c++高阶]AVL树的深度剖析模拟实现

1.前言 如果你不知道什么是二叉搜索树&#xff0c;那么请你一定要阅读以下文章。 [c高阶]二叉搜索树深度剖析-CSDN博客 二叉搜索树如果在已经有序的情况下进行插入的话&#xff0c;那么他的时间复杂度是O(N)&#xff0c;然后有时候的时间复杂度又是O(logN)&#xff0c;因此在实…

我在命令行下剪辑视频

是的&#xff0c;你不需要格式工厂&#xff0c;你也不需要会声会影&#xff0c;更不需要爱剪辑这些莫名其妙的流氓软件&#xff0c;命令行下视频处理&#xff0c;包括剪辑&#xff0c;转码&#xff0c;提取&#xff0c;合成&#xff0c;缩放&#xff0c;字幕&#xff0c;特效等…

Tita:什么是 360 评估?

360 评估是一个专业的反馈机会&#xff0c;使一组同事和经理能够提供有关同事绩效的反馈。与仅由其经理评估员工工作绩效的典型员工绩效评估不同&#xff0c;360 评估会考虑来自同事和报告员工的反馈&#xff0c;甚至包括客户和与员工互动的其他人。 Tita&#xff1a;什么是 3…

jenkins ssh 免密报错Host key verification failed.

jenkins 发布项目&#xff0c;ssh连接远程服务器时报错&#xff1a;Host key verification failed. 解决&#xff1a; 原因是生成的sshkey不是用的jenkins用户&#xff0c;所以切换用户到&#xff1a;jenkins重新生成sshkey su jenkins ssh-keygen -t rsa ssh-copy-id -i ~/…

【Linux第七课--基础IO】内存级文件、重定向、缓冲区、文件系统、动态库静态库

目录 引入内存级文件重新使用C文件接口 -- 对比重定向写文件读文件文件流 认识文件操作的系统接口open参数 -- flagflag的内容宏的传参方式 open关闭文件写文件读文件结论 引入文件描述符fd、对文件的理解理解一切皆文件方法集文件fd的分配规则 重定向代码的重定向输入重定向输…

创意设计的起点:十大网页设计模板网站

对于网页设计领域的专业人士和爱好者而言&#xff0c;从零开始构建一个网页可能会耗费大量的时间和劳力。幸运的是&#xff0c;我们可以通过使用现成的网页模板来提升工作效率并节省宝贵的时间。一个好的模板不仅能提高设计效率&#xff0c;还能激发出卓越的创意灵感。因此&…

鸿蒙Harmony-矩形绘制组件Rect使用详解

目录 一&#xff0c;定义 二&#xff0c;绘制自定义图形 三&#xff0c;作为其他控件背景使用 一&#xff0c;定义 Rect是鸿蒙提供的矩形绘制组件&#xff0c;利用该组件可以绘制矩形背景&#xff0c;矩形图案等 官方提供的参数和属性&#xff1a; 参数&#xff1a; 参数名…

netty之bootstrap源码分析

写在前面 本文看下bootstrap类。 1&#xff1a;正文 1.1&#xff1a;干啥的&#xff1f; 在进行netty编程的时候都是先创建一个bootstrap&#xff0c;然后设置很多的东西&#xff0c;如下代码&#xff08;服务端启动代码&#xff09;&#xff1a; ServerBootstrap b new …

c# WinForm弹出窗体时不获取焦点方法

WinForm开发的软件有时候需要在屏幕右下角弹窗进行一些提示&#xff0c;通常使用new MyForm().Show()即可实现此需求。 但是当MyForm显示出来时&#xff0c;会抢走原本窗体上的光标&#xff0c;导致原本在软件上比如打字或者其他操作被中断&#xff0c;非常不人性化&#xff0…

方差和标准差哪些事儿

1.方差 在概率论与数理统计中&#xff0c;方差用来度量随机变量和其数学期望&#xff08;即均值&#xff09;之间的偏离程度。方差是各个数据与平均数之差的平方和的平均数,即: s(1/n)[(x1-x_)^2 (x2-x_)^2 …(xn-x_)^2] 其中&#xff0c;x_表示样本的平均数&#xff0c;n表示…

Hudi Upsert原理

1. 前言 如果要深入了解Apache Hudi技术的应用或是性能调优&#xff0c;那么明白源码中的原理对我们会有很大的帮助。Upsert是Apache Hudi的核心功能之一&#xff0c;主要完成增量数据在HDFS/对象存储上的修改&#xff0c;并可以支持事务。而在Hive中修改数据需要重新分区或重…

了解SQLExpress数据库

SQLExpress&#xff08;Microsoft SQL Server Express&#xff09;是由微软公司开发的一款免费且轻量级的数据库管理系统。以下是关于SQLExpress的详细解释&#xff1a; 一、定义与特点 定义&#xff1a; SQLExpress是Microsoft SQL Server的一个缩减版或基础版&#xff0c;旨在…

空天地遥感数据识别与计算

在科技飞速发展的时代&#xff0c;遥感数据的精准分析已经成为推动各行业智能决策的关键工具。从无人机监测农田到卫星数据支持气候研究&#xff0c;空天地遥感数据正以前所未有的方式为科研和商业带来深刻变革。然而&#xff0c;对于许多专业人士而言&#xff0c;如何高效地处…

JavaEE-多线程初阶(2)

目录 1.创建线程的五种写法 1.1 继承Thread类 1.2 实现Runnable接口 1.3 使用匿名内部类 1.4 使用Runnable&#xff0c;匿名内部类 1.5 引入lambda表达式 2.Thread类及常见方法 2.1 认识Thread 2.2 Thread的常见构造方法 2.3 Thread的几个常见属性 关于后台线程 关…

【网络安全】揭示 Web 缓存污染与欺骗漏洞

未经许可,不得转载。 文章目录 前言污染与欺骗Web 缓存污染 DoS1、HTTP 头部超大 (HHO)2、HTTP 元字符 (HMC)3、HTTP 方法覆盖攻击 (HMO)4、未键入端口5、重定向 DoS6、未键入头部7、Host 头部大小写规范化8、路径规范化9、无效头部 CP-DoS10、HTTP 请求拆分Web 缓存污染与有害…

重工业数字化转型创新实践:某国家特大型钢铁企业如何快速落地基于实时数仓的数据分析平台

使用 TapData&#xff0c;化繁为简&#xff0c;摆脱手动搭建、维护数据管道的诸多烦扰&#xff0c;轻量替代 OGG, Kettle 等同步工具&#xff0c;以及基于 Kafka 的 ETL 解决方案&#xff0c;「CDC 流处理 数据集成」组合拳&#xff0c;加速仓内数据流转&#xff0c;帮助企业…

Golang | Leetcode Golang题解之第522题最长特殊序列II

题目&#xff1a; 题解&#xff1a; func isSubseq(s, t string) bool {ptS : 0for ptT : range t {if s[ptS] t[ptT] {if ptS; ptS len(s) {return true}}}return false }func findLUSlength(strs []string) int {ans : -1 next:for i, s : range strs {for j, t : range s…

(C#面向初学者的 .NET 的生成 AI) 第 1 部分-简介

第 1 部分简介就是由Luis Quintanilla讲述本系列教程要学习哪些部分&#xff0c;基本都是介绍&#xff0c;内容不是很多。但可以先了解一下.net 生成式AI需要学习接触哪些东西。 在这个关于机器学习和AI的初学者系列中&#xff0c;Luis Quintanilla向.net开发人员介绍了基础知识…

【密码学】全同态加密基于多项式环计算的图解

全同态加密方案提供了一种惊人的能力 —— 能够在不知道数据具体内容的情况下对数据进行计算。这使得你可以在保持潜在敏感源数据私密的同时&#xff0c;得出问题的答案。 这篇文章的整体结构包括多项式环相关的数学介绍&#xff0c;基于多项式环的加密和解密是如何工作的&…