穷举vs暴搜vs深搜vs回溯vs剪枝(典型算法思想)—— OJ例题算法解析思路
回溯算法的模版
void backtrack(vector<int>& path, vector<int>& choice, ...)
{// 满⾜结束条件if (/* 满⾜结束条件 */) {// 将路径添加到结果集中res.push_back(path);return;}// 遍历所有选择for (int i = 0; i < choices.size(); i++) {// 做出选择path.push_back(choices[i]);// 做出当前选择后继续搜索backtrack(path, choices);// 撤销选择path.pop_back();}
}
目录
回溯算法的模版
一、46. 全排列 - 力扣(LeetCode)
算法代码:
1. 类的成员变量
2. permute 函数
3. dfs 函数
4. 回溯的核心思想
5. 代码的优化空间
6. 代码的复杂度分析
7. 代码的改进版本
总结
二、78. 子集 - 力扣(LeetCode)
递归流程:
解法一:算法代码(剪枝->回溯->递归出口)
1. 类的成员变量
2. subsets 函数
3. dfs 函数
4. 回溯的核心思想
5. 代码的优化空间
6. 代码的复杂度分析
7. 代码的改进版本(避免重复子集)
改进点:
8. 总结
解法二:算法代码(回溯->剪枝->递归出口)
1. 类的成员变量
2. subsets 函数
3. dfs 函数
4. 代码的核心思想
5. 代码的优化空间
6. 代码的复杂度分析
7. 代码的改进版本(避免重复子集)
改进点:
8. 总结
一、46. 全排列 - 力扣(LeetCode)
算法代码:
class Solution {vector<vector<int>> ret;vector<int> path;bool check[7];public:vector<vector<int>> permute(vector<int>& nums) {dfs(nums);return ret;}void dfs(vector<int>& nums) {if (path.size() == nums.size()) {ret.push_back(path);return;}for (int i = 0; i < nums.size(); i++) {if (!check[i]) {path.push_back(nums[i]);check[i] = true;dfs(nums);// 回溯 -> 恢复现场path.pop_back();check[i] = false;}}}
};
1. 类的成员变量
-
ret
:用于存储所有可能的排列结果,类型为vector<vector<int>>
。 -
path
:用于存储当前正在构建的排列,类型为vector<int>
。 -
check
:用于标记某个元素是否已经被使用过,类型为bool
数组,大小为 7(假设输入数组的长度不超过 7)。
2. permute
函数
-
这是主函数,接收一个整数数组
nums
作为输入,并返回所有可能的排列。 -
调用
dfs(nums)
开始深度优先搜索。 -
最终返回
ret
,即所有排列的结果。
3. dfs
函数
-
这是递归函数,用于生成所有可能的排列。
-
递归终止条件:如果
path
的大小等于nums
的大小,说明当前path
已经是一个完整的排列,将其加入到ret
中,并返回。 -
递归过程:
-
遍历
nums
数组中的每一个元素。 -
如果当前元素没有被使用过(
check[i] == false
),则将其加入到path
中,并标记为已使用。 -
递归调用
dfs
,继续生成下一个位置的元素。 -
回溯:在递归返回后,撤销当前的选择(即从
path
中移除最后一个元素,并将check[i]
重新标记为未使用),以便尝试其他可能的排列。
-
4. 回溯的核心思想
-
回溯是一种通过递归来尝试所有可能的选择,并在每一步撤销选择以回到上一步的算法。
-
在这段代码中,回溯体现在
path.pop_back()
和check[i] = false
这两行代码上。它们的作用是撤销当前的选择,以便尝试其他可能的排列。
5. 代码的优化空间
-
check
数组的大小是固定的 7,这意味着如果nums
的大小超过 7,代码将无法正确处理。可以将check
数组的大小动态设置为nums.size()
。 -
可以使用
std::swap
来直接在原数组上进行排列,从而减少path
和check
的使用,进一步优化空间复杂度。
6. 代码的复杂度分析
-
时间复杂度:O(n!),其中 n 是
nums
的大小。因为全排列的数量是 n!。 -
空间复杂度:O(n!),用于存储所有排列的结果。递归栈的深度为 n,因此递归的空间复杂度为 O(n)。
7. 代码的改进版本
class Solution {vector<vector<int>> ret;public:vector<vector<int>> permute(vector<int>& nums) {dfs(nums, 0);return ret;}void dfs(vector<int>& nums, int start) {if (start == nums.size()) {ret.push_back(nums);return;}for (int i = start; i < nums.size(); i++) {swap(nums[start], nums[i]);dfs(nums, start + 1);swap(nums[start], nums[i]); // 回溯}}
};
在这个改进版本中,我们直接在原数组上进行排列,减少了 path
和 check
的使用,从而优化了空间复杂度。
总结
这段代码通过深度优先搜索和回溯的思想,实现了全排列的生成。代码的核心在于递归和回溯的处理,通过撤销选择来尝试所有可能的排列。
二、78. 子集 - 力扣(LeetCode)
递归流程:
解法一:算法代码(剪枝->回溯->递归出口)
// 解法⼀:
class Solution {vector<vector<int>> ret;vector<int> path;public:vector<vector<int>> subsets(vector<int>& nums) {dfs(nums, 0);return ret;}void dfs(vector<int>& nums, int pos) {if (pos == nums.size()) {ret.push_back(path);return;}// 选path.push_back(nums[pos]);dfs(nums, pos + 1);path.pop_back(); // 恢复现场// 不选dfs(nums, pos + 1);}
};
1. 类的成员变量
-
ret
:用于存储所有子集的结果,类型为vector<vector<int>>
。 -
path
:用于存储当前正在构建的子集,类型为vector<int>
。
2. subsets
函数
-
这是主函数,接收一个整数数组
nums
作为输入,并返回所有可能的子集。 -
调用
dfs(nums, 0)
开始深度优先搜索,0
表示从数组的第一个元素开始处理。 -
最终返回
ret
,即所有子集的结果。
3. dfs
函数
-
这是递归函数,用于生成所有可能的子集。
-
递归终止条件:如果
pos
等于nums
的大小,说明已经处理完所有元素,此时path
中存储的就是一个子集,将其加入到ret
中,并返回。 -
递归过程:
-
选择当前元素:
-
将
nums[pos]
加入到path
中。 -
递归调用
dfs(nums, pos + 1)
,继续处理下一个元素。 -
在递归返回后,撤销选择(即从
path
中移除最后一个元素),以便尝试不选择当前元素的情况。
-
-
不选择当前元素:
-
直接递归调用
dfs(nums, pos + 1)
,跳过当前元素,继续处理下一个元素。
-
-
4. 回溯的核心思想
-
回溯是一种通过递归来尝试所有可能的选择,并在每一步撤销选择以回到上一步的算法。
-
在这段代码中,回溯体现在
path.pop_back()
这一行代码上。它的作用是撤销当前的选择,以便尝试不选择当前元素的情况。
5. 代码的优化空间
-
如果输入数组
nums
中包含重复元素,这段代码会生成重复的子集。可以通过排序和剪枝来避免重复子集的生成。 -
可以将
path
改为引用传递,减少拷贝的开销。
6. 代码的复杂度分析
-
时间复杂度:O(2^n),其中 n 是
nums
的大小。因为每个元素有两种选择(选或不选),总共有 2^n 个子集。 -
空间复杂度:O(n),递归栈的深度为 n。结果存储空间不计入空间复杂度。
7. 代码的改进版本(避免重复子集)
如果输入数组 nums
中包含重复元素,可以通过排序和剪枝来避免生成重复的子集。改进后的代码如下:
class Solution {vector<vector<int>> ret;vector<int> path;public:vector<vector<int>> subsets(vector<int>& nums) {sort(nums.begin(), nums.end()); // 排序,便于剪枝dfs(nums, 0);return ret;}void dfs(vector<int>& nums, int pos) {ret.push_back(path); // 每次递归都加入当前子集for (int i = pos; i < nums.size(); i++) {if (i > pos && nums[i] == nums[i - 1]) continue; // 剪枝,避免重复path.push_back(nums[i]);dfs(nums, i + 1);path.pop_back(); // 回溯}}
};
改进点:
-
排序:先对
nums
排序,使得相同的元素相邻。 -
剪枝:在递归过程中,如果当前元素和前一个元素相同,并且不是第一次遇到该元素,则跳过,避免重复子集。
-
提前加入子集:在每次递归开始时,直接将当前
path
加入到ret
中,这样可以避免在递归终止时才加入子集。
8. 总结
这段代码通过深度优先搜索和回溯的思想,实现了求解数组的所有子集。代码的核心在于对每个元素的选择和不选择两种情况的分支处理,并通过回溯撤销选择以尝试其他可能性。如果输入数组包含重复元素,可以通过排序和剪枝来优化,避免生成重复子集。
解法二:算法代码(回溯->剪枝->递归出口)
// 解法⼆:
class Solution {vector<vector<int>> ret;vector<int> path;public:vector<vector<int>> subsets(vector<int>& nums) {dfs(nums, 0);return ret;}void dfs(vector<int>& nums, int pos) {ret.push_back(path);for (int i = pos; i < nums.size(); i++) {path.push_back(nums[i]);dfs(nums, i + 1);path.pop_back(); // 恢复现场}}
};
1. 类的成员变量
-
ret
:用于存储所有子集的结果,类型为vector<vector<int>>
。 -
path
:用于存储当前正在构建的子集,类型为vector<int>
。
2. subsets
函数
-
这是主函数,接收一个整数数组
nums
作为输入,并返回所有可能的子集。 -
调用
dfs(nums, 0)
开始深度优先搜索,0
表示从数组的第一个元素开始处理。 -
最终返回
ret
,即所有子集的结果。
3. dfs
函数
-
这是递归函数,用于生成所有可能的子集。
-
递归过程:
-
将当前子集加入结果:
-
在每次递归调用开始时,直接将当前
path
加入到ret
中。这是因为path
在每一层递归中都表示一个有效的子集。
-
-
遍历数组元素:
-
从当前位置
pos
开始遍历nums
数组。 -
将当前元素
nums[i]
加入到path
中,表示选择该元素。 -
递归调用
dfs(nums, i + 1)
,继续处理下一个元素。 -
在递归返回后,撤销选择(即从
path
中移除最后一个元素),以便尝试其他可能的子集。
-
-
4. 代码的核心思想
-
子集的生成:
-
子集的生成可以看作是对每个元素的选择或不选择。
-
通过递归和回溯,代码枚举了所有可能的选择组合。
-
-
提前加入子集:
-
在每次递归调用开始时,直接将当前
path
加入到ret
中。这是因为path
在每一层递归中都表示一个有效的子集,无需等到递归终止才加入。
-
5. 代码的优化空间
-
如果输入数组
nums
中包含重复元素,这段代码会生成重复的子集。可以通过排序和剪枝来避免重复子集的生成。 -
可以将
path
改为引用传递,减少拷贝的开销。
6. 代码的复杂度分析
-
时间复杂度:O(2^n),其中 n 是
nums
的大小。因为每个元素有两种选择(选或不选),总共有 2^n 个子集。 -
空间复杂度:O(n),递归栈的深度为 n。结果存储空间不计入空间复杂度。
7. 代码的改进版本(避免重复子集)
如果输入数组 nums
中包含重复元素,可以通过排序和剪枝来避免生成重复的子集。改进后的代码如下:
class Solution {vector<vector<int>> ret;vector<int> path;public:vector<vector<int>> subsets(vector<int>& nums) {sort(nums.begin(), nums.end()); // 排序,便于剪枝dfs(nums, 0);return ret;}void dfs(vector<int>& nums, int pos) {ret.push_back(path); // 将当前子集加入结果for (int i = pos; i < nums.size(); i++) {if (i > pos && nums[i] == nums[i - 1]) continue; // 剪枝,避免重复path.push_back(nums[i]);dfs(nums, i + 1);path.pop_back(); // 回溯}}
};
改进点:
-
排序:先对
nums
排序,使得相同的元素相邻。 -
剪枝:在递归过程中,如果当前元素和前一个元素相同,并且不是第一次遇到该元素,则跳过,避免重复子集。
8. 总结
这段代码通过深度优先搜索和回溯的思想,实现了求解数组的所有子集。与解法一相比,解法二的代码更加简洁,直接通过循环和递归来生成所有子集。如果输入数组包含重复元素,可以通过排序和剪枝来优化,避免生成重复子集。代码的核心思想是对每个元素的选择和不选择进行枚举,并通过回溯撤销选择以尝试其他可能性。
重点:
递归的本质
递归是一种通过函数调用自身来解决问题的编程技巧。在递归过程中,问题的规模会逐渐减小,直到达到一个终止条件。递归的核心思想是分治,即将一个大问题分解为若干个小问题,然后分别解决这些小问题。
在子集问题中,递归的作用是对每个元素做出决策(选或不选),从而生成所有可能的子集。
为什么解法一不需要 for
循环?
在解法一中,递归的逻辑是对每个元素做出“选”或“不选”的决策。具体来说:
-
对于当前元素
nums[pos]
,有两种选择:-
选择它:将其加入
path
,然后递归处理下一个元素(pos + 1
)。 -
不选择它:直接递归处理下一个元素(
pos + 1
)。
-
-
递归的终止条件是
pos == nums.size()
,表示已经处理完所有元素。
这种递归逻辑已经隐含了对所有元素的遍历,因此不需要显式的 for
循环。
为什么解法二需要 for
循环?
在解法二中,递归的逻辑是显式地遍历数组中的元素,依次生成子集。具体来说:
-
for
循环从pos
开始遍历数组nums
,表示从当前位置开始选择元素。 -
对于每个元素
nums[i]
,将其加入path
,然后递归处理下一个元素(i + 1
)。 -
在递归返回后,通过
path.pop_back()
回溯,恢复现场,尝试下一个元素。
这种递归逻辑通过 for
循环显式地遍历元素,确保每个元素都有机会被选中,并且避免生成重复的子集。
递归和 for
循环的关系
-
递归的本质是遍历:递归确实可以遍历所有元素,但遍历的方式可以是隐式的(如解法一)或显式的(如解法二)。
-
是否需要
for
循环:取决于递归的逻辑设计。如果递归的逻辑已经隐含了对所有元素的遍历(如解法一),则不需要for
循环;如果需要显式地遍历元素(如解法二),则需要for
循环。
两种解法的对比
特性 | 解法一(无 for 循环) | 解法二(有 for 循环) |
---|---|---|
递归逻辑 | 对每个元素做出“选”或“不选”的决策 | 显式遍历元素,生成子集 |
是否需要 for 循环 | 否 | 是 |
代码结构 | 更简洁 | 更直观 |
时间复杂度 | O(2^n) | O(2^n) |
为什么解法二需要 for
循环?
解法二的递归逻辑是通过 for
循环显式地遍历元素,确保每个元素都有机会被选中,并且避免生成重复的子集。具体来说:
-
显式遍历元素:
for
循环从pos
开始遍历数组nums
,表示从当前位置开始选择元素。 -
避免重复子集:通过
for
循环从pos
开始遍历,可以避免生成重复的子集。例如,如果已经选择了nums[1]
,那么后续的子集只能从nums[2]
开始选择,而不能回头选择nums[0]
。 -
生成所有子集:通过
for
循环和递归的结合,确保所有可能的子集都被生成。
总结
-
递归确实可以遍历所有元素,但遍历的方式可以是隐式的(如解法一)或显式的(如解法二)。
-
是否需要
for
循环取决于递归的逻辑设计。如果递归的逻辑已经隐含了对所有元素的遍历,则不需要for
循环;如果需要显式地遍历元素,则需要for
循环。 -
解法一和解法二都是正确的,只是它们的递归逻辑和实现方式不同。解法一更简洁,解法二更直观。
相关文章:
穷举vs暴搜vs深搜vs回溯vs剪枝(典型算法思想)—— OJ例题算法解析思路
回溯算法的模版 void backtrack(vector<int>& path, vector<int>& choice, ...) {// 满⾜结束条件if (/* 满⾜结束条件 */) {// 将路径添加到结果集中res.push_back(path);return;}// 遍历所有选择for (int i 0; i < choices.size(); i) {// 做出选择…...
java23种设计模式-命令模式
命令模式(Command Pattern)学习笔记 1. 模式定义 行为型设计模式,将请求封装为对象,使请求的发送者与接收者解耦。支持请求的排队、记录、撤销/重做等操作。 2. 适用场景 ✅ 需要将操作参数化 ✅ 需要支持事务操作(…...
交流异步电动机PI双闭环SVPWM矢量控制Simulink
关注微♥“电机小子程高兴的MATLAB小屋”获取专属优惠 1.模型简介 本仿真模型基于MATLAB/Simulink(版本MATLAB 2017Ra)软件。建议采用matlab2017 Ra及以上版本打开。(若需要其他版本可联系代为转换) 2.仿真算法: (…...
利用 Open3D 保存并载入相机视角的简单示例
1. 前言 在使用 Open3D 进行三维可视化和点云处理时,有时需要将当前的视角(Camera Viewpoint)保存下来,以便下次再次打开时能够还原到同样的视角。本文将演示如何在最新的 Open3D GUI 界面(o3d.visualization.gui / o…...
kiln微调大模型-使用deepseek R1去训练一个你的具备推理能力的chatGPT 4o
前言 随着deepseek的爆火,对于LLM的各种内容也逐渐步入我的视野,我个人认为,可能未来很长一段时间,AI将持续爆火,进入一段时间的井喷期,AI也会慢慢的走入我们每个家庭之中,为我们的生活提供便利…...
《从Kokoro看开源语音模型的“无限可能”》:此文为AI自动生成
开源语音模型 Kokoro 是一款轻量级、高性能的文本转语音(TTS)模型,以下是关于它的详细介绍: 核心优势 卓越的音质:即使参数规模仅 8200 万,也能生成自然流畅、富有表现力的语音。轻量高效:占用资源少,运行速度快,在 CPU 上即可实现近乎实时的语音生成,在 GPU 端则能…...
Spring 事务和事务传播机制(详解)
1 .事务 1.1.什么是事务? 事务是一组操作的集合,是不可分割的操作 事务作为一个整体,要不同时完成,要不同时失败 1.2什么时候需要事务? 关于金钱的操作基本都会有事务 例如转账操作: 第一步 A账号 - 500元第二步 B账…...
Innodb MVCC实现原理
什么是MVCC? MVCC全称多版本并发控制,是在并发访问数据库时对操作数据做多版本管理,避免因为写数据时要加写锁而阻塞读取数据的请求问题。 Innodb对mvcc的实现 1、事务版本号 每次事务开启前都会从数据库获得一个自增长的事务ID,可以从事…...
【网络编程】网络套接字和使用案例
一、为什么大多数网络编程使用套接字 在网络编程中,套接字 (socket) 是最常用的接口,但并不是所有的底层通信都依赖于套接字。尽管如此,绝大多数网络应用(特别是在操作系统层面)都使用套接字进行通信,因为…...
【Java企业生态系统的演进】从单体J2EE到云原生微服务
Java企业生态系统的演进:从单体J2EE到云原生微服务 目录标题 Java企业生态系统的演进:从单体J2EE到云原生微服务摘要1. 引言2. 整体框架演进:从原始Java到Spring Cloud2.1 原始Java阶段(1995-1999)2.2 J2EE阶段&#x…...
【爬虫基础】第二部分 爬虫基础理论 P1/3
上节内容回顾:【爬虫基础】第一部分 网络通讯 P1/3-CSDN博客 【爬虫基础】第一部分 网络通讯-Socket套接字 P2/3-CSDN博客 【爬虫基础】第一部分 网络通讯-编程 P3/3-CSDN博客 爬虫相关文档,希望互相学习,共同进步 风123456789ÿ…...
第2章_保护您的第一个应用程序
第2章_保护您的第一个应用程序 在本章中,您将学习如何使用 Keycloak 保护您的第一个应用程序。为了让事情更有趣,您将运行的示例应用程序由两部分组成,前端 Web 应用程序和后端 REST API。这将向您展示用户如何向前端进行身份验证࿰…...
山东大学软件学院人工智能导论实验之知识库推理
目录 实验目的: 实验代码: 实验内容: 实验结果 实验目的: 输入相应的条件,根据知识库推理得出相应的知识。 实验代码: def find_data(input_process_data_list):for epoch, data_process in enumerat…...
Java 网络协议面试题答案整理,最新面试题
TCP和UDP的主要区别是什么? TCP(传输控制协议)和UDP(用户数据报协议)的主要区别在于TCP是面向连接的协议,而UDP是无连接的协议。这导致了它们在数据传输方式、可靠性、速度和使用场景方面的不同。 1、连接…...
win10把c盘docker虚拟硬盘映射迁移到别的磁盘
c盘空间本身就比较小、如果安装了docker服务后,安装的时候没选择其他硬盘,虚拟磁盘也在c盘会占用很大的空间,像我的就三十多个G,把它迁移到其他磁盘一下子节约几十G 1、先输入下面命令查看 docker 状态 wsl -l -v 2、如果没有停止…...
AOP进阶-02.通知顺序
一.通知顺序 当有多个切面类中的切入点表达式一样时,这些切面类的执行顺序是怎样的呢?如图我们将定义两个切面类,一个MyAspect2,一个MyAspect3,一个MyAspect4。执行后我们发现, 对于目标方法前的通知方法&…...
${sym} 与 String(sym) 的区别
在 JavaScript 中,${sym}(模板字符串插值)和 String(sym)(显式类型转换)虽然都涉及将值转换为字符串,但它们的底层逻辑和行为存在显著差异,尤其是在处理 Symbol 等特殊类型时。以下是具体对比&a…...
sglang框架源码笔记
文章目录 整体架构1. **客户端(Client)**:2. **服务器端(Server)**:3. **调度器与模型工作节点(Scheduler & Model Worker)**: TpModelWorker类ModelRunner类TpModel…...
2025年SCI一区智能优化算法:混沌进化优化算法(Chaotic Evolution Optimization, CEO),提供MATLAB代码
一、混沌进化优化算法 https://github.com/ITyuanshou/MATLABCode 1. 算法简介 混沌进化优化算法(Chaotic Evolution Optimization, CEO)是2025年提出的一种受混沌动力学启发的新型元启发式算法。该算法的主要灵感来源于二维离散忆阻映射的混沌进化过…...
uake 网络安全 reverse网络安全
🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 本文首发于“合天网安实验室” 首先从PEID的算法分析插件来介绍,要知道不管是在CTF竞赛的REVERSE题目中,还是在实际的商业产品中…...
C语言实现单链表
单链表是数据结构中最基础的链式结构,它不按照线性的顺序存储数据,而是由若干个同一结构类型的“节点”依次串联而成的,即每一个节点里保存着下一个节点的地址(指针)。 上图中,一个表头变量head是用来存储链表首节点的地址,链表中每个节点有data(数据)部分和n…...
Rk3568驱动开发_点亮led灯代码完善(手动挡)_6
1.实现思路: 应用层打开设备后通过write函数向内核中写值,1代表要打开灯,0代表要关闭灯 Linux配置gpio和控制gpio多了一个虚拟内存映射操作 2.注意事项: 配置和读写操作的时候要谨慎,比如先关掉gpio再注销掉虚拟内存…...
threejs:document.createElement创建标签后css设置失效
vue3threejs,做一个给模型批量CSS2D标签的案例,在导入模型的js文件里,跟着课程写的代码如下: import * as THREE from three; // 引入gltf模型加载库GLTFLoader.js import { GLTFLoader } from three/addons/loaders/GLTFLoader.…...
在 compare-form.vue 中添加 compareDate 隐藏字段,并在提交时自动填入当前时间
在 compare-form.vue 中添加 compareDate 隐藏字段,并在提交时自动填入当前时间。 提交表单时存入的对象是FakeRegistration,这个对象里面有compareDate字段,刚好表格查询的对象也是FakeRegistration,所以表格展示的时间就是刚才…...
使用DeepSeek/ChatGPT等AI工具辅助编写wireshark过滤器
随着deepseek,chatgpt等大模型的能力越来越强大,本文将介绍借助deepseek,chatgpt等大模型工具,通过编写提示词,辅助生成全面的Wireshark显示过滤器的能力。 每一种协议的字段众多,流量分析的需求多种多样,…...
Java 大视界 -- Java 大数据在智能物流路径规划与车辆调度中的创新应用(102)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
YOLOv12 ——基于卷积神经网络的快速推理速度与注意力机制带来的增强性能结合
概述 实时目标检测对于许多实际应用来说已经变得至关重要,而Ultralytics公司开发的YOLO(You Only Look Once,只看一次)系列一直是最先进的模型系列,在速度和准确性之间提供了稳健的平衡。注意力机制的低效阻碍了它们在…...
一个行为类似标准库find算法的模板
函数需要两个模板类型参数,一个表示函数的迭代器参数,另一个表示值的类型。 代码 #include<iostream> #include<string> #include<vector> #include<list>using namespace std;template <typename IterType,typename T>…...
LLC谐振变换器恒压恒流双竞争闭环simulink仿真
1.模型简介 本仿真模型基于MATLAB/Simulink(版本MATLAB 2017Ra)软件。建议采用matlab2017 Ra及以上版本打开。(若需要其他版本可联系代为转换)针对全桥LLC拓扑,利用Matlab软件搭建模型,分别对轻载…...
Elasticsearch 的分布式架构原理:通俗易懂版
Elasticsearch 的分布式架构原理:通俗易懂版 Lucene 和 Elasticsearch 的前世今生 Lucene 是一个功能强大的搜索库,提供了高效的全文检索能力。然而,直接基于 Lucene 开发非常复杂,即使是简单的功能也需要编写大量的 Java 代码&…...
[深度学习]基于C++和onnxruntime部署yolov12的onnx模型
基于C和ONNX Runtime部署YOLOv12的ONNX模型,可以遵循以下步骤: 准备环境:首先,确保已经下载后指定版本opencv和onnruntime的C库。 模型转换: 安装好yolov12环境并将YOLOv12模型转换为ONNX格式。这通常涉及使用深度学习…...
seacmsv9报错注入
1、seacms的介绍 seacms中文名:海洋影视管理系统。是一个采用了php5mysql架构的影视网站框架,因此,如果该框架有漏洞,那使用了该框架的各个网站都会有相同问题。 2、源码的分析 漏洞的部分源码如下: <?php …...
剑指 Offer II 033. 变位词组
comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20033.%20%E5%8F%98%E4%BD%8D%E8%AF%8D%E7%BB%84/README.md 剑指 Offer II 033. 变位词组 题目描述 给定一个字符串数组 strs ,将 变位词 组合在一起…...
【2025全网最新最全】前端Vue3框架的搭建及工程目录详解
文章目录 安装软件Node.js搭建Vue工程创建Vue工程精简Vue项目文件 Vue工程目录的解读网页标题的设置设置全局样式路由配置 安装软件Node.js 下载地址:https://nodejs.org/zh-cn/ 安装完成后,打开cmd,查看环境是否准备好 node -v npm -vnpm使用之前一定…...
前缀和专题练习 ——基于罗勇军老师的《蓝桥杯算法入门C/C++》
目录 一、0求和 - 蓝桥云课 算法代码: 代码思路概述 代码详细解释 数组定义 输入读取 前缀和计算部分 结果计算部分 输出结果 程序结束 总结 二、1.可获得的最小取值 - 蓝桥云课 算法代码: 代码思路概述 详细代码逻辑解释 输入初始化 …...
1.测试策略与计划设计指南
1.介绍 1.1项目介绍 完整项目组成:1.基于K8S定制开发的SaaS平台;2.多个团队提供的中台服务(微服务);3.多个业务团队开发的系统平台。涉及多个项目团队、上百个微服务组件。 测试在所有团队开发测试后,自己搭建测试环境,…...
pikachu
暴力破解 基于表单的暴力破解 【2024版】最新BurpSuit的使用教程(非常详细)零基础入门到精通,看一篇就够了!让你挖洞事半功倍!_burpsuite使用教程-CSDN博客 登录页面,随意输入抓包,发送到攻击…...
HDFS扩缩容及数据迁移
1.黑白名单机制 在HDFS中可以通过黑名单、白名单机制进行节点管理,决定数据可以复制/不可以复制到哪些节点。 黑名单通常是指在HDFS中被标记为不可用或不可访问的节点列表,这些节点可能由于硬件故障、网络问题或其他原因而暂时或永久性地无法使用。当一…...
设计模式-(状态模式,策略模式,代理模式,责任链模式)
状态模式 概念: 用于管理一个对象在不同状态下的行为变化。它允许对象在内部状态改变时改变其行为,从而让对象看起来像是改变了其类。状态模式的核心思想是将状态封装到独立的类中,每个状态类都定义了在该状态下对象的行为 状态模式主要涉…...
二、IDE集成DeepSeek保姆级教学(使用篇)
各位看官老爷好,如果还没有安装DeepSeek请查阅前一篇 一、IDE集成DeepSeek保姆级教学(安装篇) 一、DeepSeek在CodeGPT中使用教学 1.1、Edit Code 编辑代码 选中代码片段 —> 右键 —> CodeGPT —> Edit Code, 输入自然语言可编辑代码,点击S…...
通义灵码插件安装入门教学 - IDEA(安装篇)
在开发过程中,使用合适的工具和插件可以极大地提高我们的工作效率。今天,我们将详细介绍如何在 IntelliJ IDEA 中安装并配置通义灵码插件,这是一款旨在提升开发者效率的实用工具。无论你是新手还是有经验的开发者,本文都将为你提供…...
每天一个Flutter开发小项目 (4) : 构建收藏地点应用 - 深入Flutter状态管理
引言 欢迎回到 每天一个Flutter开发小项目 系列博客!在前三篇博客中,我们从零开始构建了计数器应用、待办事项列表应用,以及简易天气应用。您不仅掌握了 Flutter 的基础组件和布局,还学习了网络请求、JSON 解析等实用技能,更重要的是,我们一起探讨了高效的 Flutter 学习…...
qt-C++笔记之QtCreator新建项目即Create Project所提供模板的逐个尝试
qt-C笔记之QtCreator新建项目即Create Project所提供模板的逐个尝试 code review! 文章目录 qt-C笔记之QtCreator新建项目即Create Project所提供模板的逐个尝试1.Application(Qt):Qt Widgets Application1.1.qmake版本1.2.cmake版本 2.Application(Qt):Qt Console Applicati…...
【NestJS系列】安装官方nestjs CLI 工具
环境搭建指南:从零开始创建 NestJS 项目 一、工具准备 1. 安装 Node.js 环境 推荐使用 LTS 版本(目前 20.x 以上)验证安装:终端执行 node -v 和 npm -vNode.js 官网下载2. 包管理器选择 这里选用更高效的 pnpm,你也可选择 npm 或 yarn # 安装 pnpm npm install -g pnp…...
【Springboot知识】Logback从1.2.x升级到1.3.x需要注意哪些点?
文章目录 **1. 确认依赖版本**示例依赖配置(Maven): **2. 处理 StaticLoggerBinder 的移除**解决方案: **3. 修改日志配置文件**示例 logback.xml 配置: **4. 检查兼容性问题**Spring Boot 2.x 的兼容性解决方案&#…...
【Linux C | 时间】localtime 的介绍、死机、死锁问题以及 localtime_r 函数的时区问题
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...
每日一题——LRU缓存机制的C语言实现详解
LRU缓存机制的C语言实现详解 参考1. 数据结构设计双向链表节点哈希表节点哈希表LRU缓存结构 2. 初始化哈希表和双向链表哈希函数初始化哈希表初始化双向链表创建LRU缓存 3. 更新双向链表4. 实现Get操作5. 实现Put操作更新节点值删除最久未使用节点插入或更新节点 6. 释放缓存释…...
虚函数表和虚函数表指针
1.虚函数表什么时候生成? 编译器编译的时候生成 2.虚函数表存放在哪里? 讨论两种情况:在磁盘(可执行程序)、在内存(运行状态) 3.虚函数表与虚函数表指针的关系 每个类只有一个虚函数&#x…...
计算机毕业设计SpringBoot+Vue.js图书进销存管理系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
3-2 WPS JS宏 工作簿的打开与保存(模板批量另存为工作)学习笔记
************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…...