【优选算法篇】踏入算法的深邃乐章:滑动窗口的极致探秘

文章目录

  • C++ 滑动窗口详解:进阶题解与思维分析
    • 前言
    • 第二章:进阶挑战
      • 2.1 水果成篮
        • 解法一:滑动窗口
        • 解法二:滑动窗口 + 数组模拟哈希表
        • 复杂度分析:
        • 图解分析:
          • 示例:
          • 滑动窗口执行过程图解:
        • 详细说明:
      • 2.2 找到字符串中所有字母异位词
        • 解法:滑动窗口 + 哈希表
        • 复杂度分析:
        • 图解分析:
          • 滑动窗口执行过程图解:
        • 详细说明:
      • 2.3 串联所有单词的子串
        • 解法:滑动窗口+哈希表
        • 复杂度分析:
        • 图解分析:
          • 滑动窗口执行过程图解:
        • 详细说明:
      • 2.4 最小覆盖子串
        • 解法:滑动窗口 + 哈希表
        • 复杂度分析:
        • 图解分析:
          • 滑动窗口执行过程图解:
        • 详细说明:
    • 写在最后

C++ 滑动窗口详解:进阶题解与思维分析

💬 欢迎讨论:如有疑问或见解,欢迎在评论区留言互动。

👍 点赞、收藏与分享:如觉得这篇文章对您有帮助,请点赞、收藏并分享!
🚀 分享给更多人:欢迎分享给更多对 C++ 感兴趣的朋友,一起学习滑动窗口的基础与进阶!


前言

接上篇【优选算法篇】编织算法的流动诗篇:滑动窗口的轻盈之美

在算法的世界中,滑动窗口是一种极具优雅和灵活性的算法技巧。在上一章中,我们通过几个经典问题初步领略了滑动窗口的强大之处。然而,算法的探索并没有止步于此。随着问题的复杂性逐渐提升,滑动窗口的应用场景也变得更加丰富多样。在这篇博客中,我们将继续深入探讨滑动窗口的进阶应用。通过更加灵活的策略、动态调整窗口,我们将解决一系列复杂的算法挑战,进一步揭示滑动窗口的无限可能。

接下来,让我们步入滑动窗口的进阶领域,探索更多算法之美。


第二章:进阶挑战

2.1 水果成篮

题目链接:904. 水果成篮

题目描述
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果种类。你想要尽可能多地收集水果,但是有一些规则:

  • 你有两个篮子,每个篮子只能装一种类型的水果,篮子的容量无限制。
  • 你可以选择任意一棵树开始采摘,但必须从这棵树开始依次向右采摘每棵树上的水果。
  • 一旦遇到某棵树上的水果不符合篮子中的水果种类,你必须停止采摘。

返回你能采摘的最多的水果数量。

示例 1

  • 输入:fruits = [1,2,1]
  • 输出:3
  • 解释:你可以采摘所有 3 棵树上的水果。

示例 2

  • 输入:fruits = [0,1,2,2]
  • 输出:3
  • 解释:你只能采摘 [1,2,2] 这三棵树的水果。如果从第 1 棵树开始采摘,只能采摘到 [0,1]。

示例 3

  • 输入:fruits = [3,3,3,1,2,1,1,2,3,3,4]
  • 输出:5
  • 解释:你可以采摘 [1,2,1,1,2] 这五棵树的水果。

提示:

  • 1 <= fruits.length <= 105
  • 0 <= fruits[i] < fruits.length

解法一:滑动窗口

算法思路

本题是典型的滑动窗口问题。要求我们找到一个连续区间,其中只能有两种不同种类的水果(即至多两个不同元素)。通过滑动窗口,我们可以动态调整区间大小,保持窗口内水果种类不超过两种。

具体步骤:

  1. 用一个哈希表 hash 记录滑动窗口内的水果种类和数量。
  2. 滑动窗口的右边界 right 向右移动,每次将新水果加入哈希表。
  3. 如果哈希表中记录的水果种类超过两个,左边界 left 开始向右移动,直到窗口内水果种类不超过两个为止。
  4. 在每次满足条件时,更新最大收集到的水果数量 ret

算法流程

  1. 初始化哈希表 hash,左右指针 leftright,以及记录结果的变量 ret
  2. 遍历数组 fruits,对每个水果进行如下操作:
    • right 指向的水果加入哈希表,统计频次。
    • 如果哈希表的大小超过 2,左指针 left 向右移动,同时更新哈希表,直到哈希表中只有两种水果。
    • 在满足条件时,更新最大采摘数量 ret
  3. 返回结果。

代码实现

#include <unordered_map>
#include <vector>
using namespace std;class Solution {
public:int totalFruit(vector<int>& fruits) {unordered_map<int, int> hash; // 统计滑动窗口内水果的种类和数量int ret = 0; // 记录最大水果数量int left = 0; // 左指针for (int right = 0; right < fruits.size(); ++right) {hash[fruits[right]]++; // 右指针扩展窗口,加入新水果// 如果种类超过 2,收缩窗口while (hash.size() > 2) {hash[fruits[left]]--; // 移除左边水果if (hash[fruits[left]] == 0) {hash.erase(fruits[left]); // 种类为 0,删除该水果}left++; // 左指针向右移动}ret = max(ret, right - left + 1); // 更新最大水果数量}return ret;}
};

解法二:滑动窗口 + 数组模拟哈希表

算法思路

利用数组 hash 来代替哈希表,用水果种类的值直接作为数组下标,来统计每种水果的数量。这种方式效率更高,因为直接使用数组的下标访问比哈希表操作更快。

代码实现

class Solution {
public:int totalFruit(vector<int>& fruits) {int hash[100001] = {0};  // 数组模拟哈希表int ret = 0;             // 记录结果int left = 0;            // 左指针int kinds = 0;           // 记录当前窗口内的水果种类数for (int right = 0; right < fruits.size(); ++right) {if (hash[fruits[right]] == 0) kinds++;  // 新种类水果进入窗口hash[fruits[right]]++;  // 统计数量// 当水果种类超过 2 时,收缩窗口while (kinds > 2) {hash[fruits[left]]--;  // 移除左边水果if (hash[fruits[left]] == 0) kinds--;  // 种类数量减少left++;  // 左指针右移}ret = max(ret, right - left + 1);  // 更新最大水果数量}return ret;}
};

复杂度分析:
  • 时间复杂度O(n),每个元素最多被左右指针访问两次。
  • 空间复杂度O(n),哈希表或数组最多存储 n 种水果的频次。

图解分析:
示例:
  • 输入fruits = [3,3,3,1,2,1,1,2,3,3,4]
  • 输出5
  • 解释:你可以采摘 [1,2,1,1,2] 这五棵树的水果。

滑动窗口执行过程图解:
IterationLeftRight水果种类窗口内水果窗口大小最大结果
1001[3]11
2011[3, 3]22
3021[3, 3, 3]33
4032[3, 3, 3, 1]44
5043[3, 3, 3, 1, 2]55
6352[1, 2, 1]35
7362[1, 2, 1, 1]45
8372[1, 2, 1, 1, 2]55
9782[2, 3]25
10792[2, 3, 3]35
118102[3, 3, 4]35

详细说明:
  1. Iteration 1-3Right 扩展到 2,窗口内只有一种水果 3,因此子数组为 [3,3,3],长度为 3
  2. Iteration 4:加入水果 1,种类增加到两种,窗口变为 [3,3,3,1],长度更新为 4
  3. Iteration 5:加入水果 2,种类增加到三种,此时需要调整窗口,移动 Left,直到只剩两种水果。经过调整,窗口变为 [1,2,1]
  4. Iteration 6-8:继续右移 Right,窗口内的水果种类保持为两种,最大长度更新为 5,子数组为 [1,2,1,1,2]
  5. Iteration 9-11:加入水果 3,水果种类再次超出限制,继续收缩窗口,最终找到的最大子数组长度为 5

2.2 找到字符串中所有字母异位词

题目链接:438. 找到字符串中所有字母异位词

题目描述

给定两个字符串 sp,找到 s 中所有 p异位词 的子串,返回这些子串的起始索引。顺序可以不考虑。

异位词是指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1

  • 输入:s = "cbaebabacd", p = "abc"
  • 输出:[0,6]
  • 解释:
    起始索引为 0 的子串是 "cba",它是 "abc" 的异位词。
    起始索引为 6 的子串是 "bac",它是 "abc" 的异位词。

示例 2

  • 输入:s = "abab", p = "ab"
  • 输出:[0,1,2]
  • 解释:
    起始索引为 0 的子串是 "ab",它是 "ab" 的异位词。
    起始索引为 1 的子串是 "ba",它是 "ab" 的异位词。
    起始索引为 2 的子串是 "ab",它是 "ab" 的异位词。

提示

  • 1 <= s.length, p.length <= 3 * 10^4
  • sp 仅包含小写字母。

解法:滑动窗口 + 哈希表

算法思路

这道题要求我们在字符串 s 中找到所有与字符串 p异位词 对应的子串。由于异位词由相同字母组成且长度与 p 相同,因此我们可以使用滑动窗口来解决这一问题。

  1. 窗口大小固定
    因为异位词的长度一定与字符串 p 的长度相同,所以我们构造一个长度为 p.size() 的滑动窗口,每次右移窗口,动态维护窗口内每个字母的出现频次。

  2. 频次匹配判断
    通过两个大小为 26 的数组来统计字母出现的次数,分别用于存储当前窗口内字母频次(hash2)和 p 中的字母频次(hash1)。当两个数组的内容相同,说明当前窗口就是 p 的一个异位词。

  3. 窗口移动
    每次右移窗口时,更新窗口内字母的频次。如果窗口超过 p.size(),需要将最左边的字母移出窗口。若在滑动过程中,两个数组的内容始终保持一致,那么我们记录该窗口的起始索引。


算法流程

  1. 初始化两个大小为 26 的数组 hash1hash2,分别记录 p 中字母的频次和窗口中字母的频次。
  2. 遍历字符串 s,使用右指针 right 逐渐扩大窗口:
    • 每次将窗口右端的字母加入窗口,并更新其频次。
    • 若窗口超过 p.size(),则需要从左侧移出一个字母,并更新频次。
  3. hash1hash2 相等时,说明当前窗口是 p 的一个异位词,记录其起始位置。
    因为直接比较两个哈希表时间复杂度很高,这里我们想到了一种优化方式,要判断窗口字符串是否是异位词,我们只需要判断同一种字符在两个字符串中出现的次数是否一样即可,这里我们使用count来统计有效字符的个数即可轻松判断窗口字符串是否是p的异位词
  4. 最后返回所有满足条件的起始位置列表。

代码实现

#include <vector>
using namespace std;class Solution {
public:vector<int> findAnagrams(string s, string p) {vector<int> ret;int hash1[26] = { 0 }; // 统计字符串 p 中每个字符出现的个数for(auto ch : p) hash1[ch - 'a']++; int hash2[26] = { 0 }; // 统计窗口里面的每一个字符出现的个数int m = p.size();for(int left = 0, right = 0, count = 0; right < s.size(); right++) {char in = s[right];// 进窗口 + 维护 countif(++hash2[in - 'a'] <= hash1[in - 'a']) count++;if(right - left + 1 > m) {  // 判断窗口是否需要收缩char out = s[left++];// 出窗口 + 维护 countif(hash2[out - 'a']-- <= hash1[out - 'a']) count--;}// 更新结果if(count == m) ret.push_back(left);}return ret;}
};

这里面count是指有效字符的个数,很巧妙的判断滑动窗口里的字符串是否满足条件


复杂度分析:
  • 时间复杂度O(n),每个字符最多被左右指针访问两次,因此时间复杂度为线性。
  • 空间复杂度O(1),只需要常数级别的额外空间用于存储两个固定大小的数组。

图解分析:

假设输入为 s = "cbaebabacd", p = "abc",通过滑动窗口的执行过程如下:

滑动窗口执行过程图解:
IterationLeftRight窗口内字母频次窗口大小当前窗口字母是否为异位词异位词起始索引
100[c]1c-
201[c, b]2cb-
302[c, b, a]3cba0
413[b, a, e]3bae-
524[a, e, b]3aeb-
635[e, b, a]3eba-
746[b, a, d]3bad-
857[a, b, a]3aba-
968[b, a, c]3bac6
1079[a, c, d]3acd-

详细说明:
  1. Iteration 1-3Right=0Right=2,窗口内包含 [c, b, a],它与 p="abc" 完全匹配,属于异位词,记录起始索引 0

  2. Iteration 4Right=3,窗口内包含 [b, a, e],字母 e 不在 p 中,因此当前窗口不是异位词。

  3. Iteration 5Right=4,窗口内包含 [a, e, b],依旧不匹配 p,当前窗口不是异位词。

  4. Iteration 6Right=5,窗口内包含 [e, b, a],仍然不匹配 p,当前窗口不是异位词。

  5. Iteration 7Right=6,窗口内包含 [b, a, d]d 不在 p 中,因此当前窗口不是异位词。

  6. Iteration 8Right=7,窗口内包含 [a, b, a],当前窗口不是异位词。

  7. Iteration 9Right=8,窗口内包含 [b, a, c],这再次是 p="abc" 的排列,属于异位词,记录起始索引 6

  8. Iteration 10Right=9,窗口内包含 [a, c, d]d 不在 p 中,因此当前窗口不是异位词。


2.3 串联所有单词的子串

题目链接:30. 串联所有单词的子串

题目描述

给定一个字符串 s 和一个字符串数组 wordswords 中所有字符串的长度相同。s 中的 串联子串 是指包含 words 中所有字符串以任意顺序排列连接起来的子串。

例如,如果 words = ["ab","cd","ef"],那么 "abcdef", "abefcd", "cdabef", "cdefab", "efabcd""efcdab" 都是串联子串,而 "acdbef" 不是串联子串,因为它不是 words 排列的连接。

返回所有串联子串在 s 中的开始索引,顺序可以不考虑。

示例 1

  • 输入:s = "barfoothefoobarman", words = ["foo","bar"]
  • 输出:[0,9]
  • 解释:
    子串 "barfoo" 的起始索引为 0,它是 words 中按顺序排列的连接。
    子串 "foobar" 的起始索引为 9,它是 words 中按顺序排列的连接。

示例 2

  • 输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
  • 输出:[]
  • 解释:
    字符串中没有符合要求的串联子串。

示例 3

  • 输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]
  • 输出:[6,9,12]
  • 解释:
    子串 "foobarthe" 的起始索引为 6,它是 words 中按顺序排列的连接。
    子串 "barthefoo" 的起始索引为 9,子串 "thefoobar" 的起始索引为 12

提示

  • 1 <= s.length <= 10^4
  • 1 <= words.length <= 5000
  • 1 <= words[i].length <= 30
  • words[i]s 仅包含小写英文字母。

解法:滑动窗口+哈希表

算法思路

本题可以类比为寻找字符串中所有字母异位词的变种问题。不同的是,这里处理的对象是单词而不是单个字符。我们需要遍历字符串 s,并通过滑动窗口找到所有符合条件的单词排列。

在这里插入图片描述

具体步骤:

  1. 使用哈希表 hash1 记录 words 中每个单词的频次。
  2. 遍历字符串 s,每次滑动窗口的大小为 words 中单词的总长度。
  3. 在每个窗口内,维护另一个哈希表 hash2,用于记录当前窗口内单词的频次。
  4. 当两个哈希表的内容一致时,说明当前窗口是一个符合要求的串联子串,记录其起始索引。
    同理,这里比较两个哈希表是否相等时间复杂度也很高,所以我们还是采用优化方式,使用count变量来统计有效字符串的个数即可

算法流程

  1. 初始化 hash1,用于存储 words 中单词的频次。
  2. 遍历 s,通过滑动窗口按单词长度为步长,维护窗口内单词的频次。
  3. 当窗口内的单词频次与 words 中的单词频次一致时,记录该窗口的起始索引。

代码实现

#include <unordered_map>
#include <vector>
#include <string>
using namespace std;class Solution {
public:vector<int> findSubstring(string s, vector<string>& words) {vector<int> ret;unordered_map<string, int> hash1;  // 保存 words 中所有单词的频次for (auto& word : words) hash1[word]++;int len = words[0].size(), m = words.size();for (int i = 0; i < len; i++) {  // 执行 len 次unordered_map<string, int> hash2;  // 维护窗口内单词的频次for (int left = i, right = i, count = 0; right + len <= s.size(); right += len) {string in = s.substr(right, len);  // 进窗口hash2[in]++;if (hash1.count(in) && hash2[in] <= hash1[in]) count++;// 判断是否需要缩小窗口if (right - left + 1 > len * m) {string out = s.substr(left, len);  // 出窗口if (hash1.count(out) && hash2[out] <= hash1[out]) count--;hash2[out]--;left += len;}// 更新结果if (count == m) ret.push_back(left);}}return ret;}
};

复杂度分析:
  • 时间复杂度O(n * m * l),其中 n 是字符串 s 的长度,mwords 中单词的个数,l 是单词的长度。每个单词被扫描一次,并且最多执行 len 次完整的窗口扫描。
  • 空间复杂度O(m * l),用于存储 words 中单词的哈希表以及滑动窗口中的哈希表。

图解分析:
滑动窗口执行过程图解:

假设输入为 s = "barfoothefoobarman", words = ["foo", "bar"],通过滑动窗口的执行过程如下:

具体过程和上一道题类似,核心没变,操作对象从单个字符变成字符串而已,以及一些细节的处理,其他都没啥了,这里就不详细分析了

IterationLeftRight窗口内单词窗口大小当前窗口单词是否为串联子串串联子串起始索引
100[bar]1bar-
203[bar, foo]2barfoo0
369[foo, bar]2foobar9

详细说明:
  1. Iteration 1:窗口内的单词为 [bar],不构成完整的串联子串。
  2. Iteration 2:窗口扩大,内含 [bar, foo],它是 words 中单词的排列,记录起始索引 0
  3. Iteration 3:窗口滑动,内含 [foo, bar],它是 words 中单词的排列,记录起始索引 9

2.4 最小覆盖子串

题目链接:76. 最小覆盖子串

题目描述

给你一个字符串 s 和一个字符串 t。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在这样的子串,则返回空字符串 ""

注意:

  • 对于 t 中重复的字符,最小子串中该字符数量必须不少于 t 中的字符数量。
  • 如果存在这样的子串,答案是唯一的。

示例 1

  • 输入:s = "ADOBECODEBANC", t = "ABC"
  • 输出:"BANC"
  • 解释:最小覆盖子串 "BANC" 包含字符串 t 的 ‘A’、‘B’ 和 ‘C’。

示例 2

  • 输入:s = "a", t = "a"
  • 输出:"a"
  • 解释:整个字符串 s 就是最小覆盖子串。

示例 3

  • 输入:s = "a", t = "aa"
  • 输出:""
  • 解释:t 中两个字符 ‘a’ 应该都出现在子串中,而 s 中只有一个 ‘a’,因此不存在符合条件的子串。

提示

  • 1 <= s.length, t.length <= 10^4
  • st 由英文字母组成。

解法:滑动窗口 + 哈希表

算法思路

这是一个典型的滑动窗口问题。目标是找到字符串 s 中能够覆盖 t 所有字符的最小子串。解决思路如下:

  1. 滑动窗口的应用

    • 我们使用两个哈希表,一个用来记录 t 中每个字符的频次,另一个用来动态维护滑动窗口中的字符频次。
    • 当窗口内的字符满足 t 中每个字符的频次要求时,窗口就是一个可行的解。
  2. 动态调整窗口大小

    • 通过不断扩大窗口右边界,将字符加入窗口。
    • 一旦窗口内的字符满足 t 的要求,开始缩小窗口左边界,尽量缩短窗口长度。

算法流程

  1. 初始化两个哈希表,hash1 用来记录 t 中每个字符的频次,hash2 用来记录窗口内的字符频次。
  2. 使用滑动窗口,右指针 right 不断向右扩展窗口,同时更新窗口内的字符频次。
  3. 每当窗口内的字符频次满足 t 中的要求,开始收缩左指针 left,缩小窗口并更新最小子串的长度。
  4. 当遍历结束后,返回最小子串的起始索引和长度。

这里面还是需要判断两个哈希表是否相等,我们这里还是采用的优化方式,使用count变量来统计有效字符,不过之前两道题是为了统计字符出现的频次,这道题我们统计的是字符出现的种类,所以count++--的情况有所变化喔


代码实现

#include <string>
#include <climits>
using namespace std;class Solution {
public:string minWindow(string s, string t) {int hash1[128] = { 0 }; // 记录字符串 t 中每个字符的频次int kinds = 0;          // 统计 t 中不同的字符种类for (auto ch : t) {if (hash1[ch]++ == 0) kinds++;}int hash2[128] = { 0 }; // 记录窗口中每个字符的频次int minlen = INT_MAX, begin = -1; // 初始化最小长度和起始位置for (int left = 0, right = 0, count = 0; right < s.size(); right++) {char in = s[right];if (++hash2[in] == hash1[in]) count++;  // 进窗口 + 维护 count// 如果当前窗口满足条件,尝试收缩窗口while (count == kinds) {if (right - left + 1 < minlen) {    // 更新最小长度和起始位置minlen = right - left + 1;begin = left;}char out = s[left++];               // 收缩窗口if (hash2[out]-- == hash1[out]) count--;  // 出窗口 + 维护 count}}// 返回结果if (begin == -1) return "";else return s.substr(begin, minlen);}
};

复杂度分析:
  • 时间复杂度O(n),其中 n 是字符串 s 的长度,滑动窗口遍历每个字符最多两次。
  • 空间复杂度O(1),哈希表的大小固定为 128,存储字符频次。

图解分析:

假设输入为 s = "ADOBECODEBANC", t = "ABC",滑动窗口的执行过程如下:

滑动窗口执行过程图解:
IterationLeftRight窗口内字符窗口大小是否为有效窗口最小子串
100[A]1-
201[A, D]2-
302[A, D, O]3-
403[A, D, O, B]4-
504[A, D, O, B, E]5-
605[A, D, O, B, E, C]6ADOBEC
716[D, O, B, E, C, O]6ADOBEC
817[D, O, B, E, C, O, D]7ADOBEC
918[D, O, B, E, C, O, D, E]8ADOBEC
1019[D, O, B, E, C, O, D, E, B]9ADOBEC
11110[D, O, B, E, C, O, D, E, B, A]10ADOBEC
12510[C, O, D, E, B, A]6ADOBEC
13610[O, D, E, B, A]5ADOBEC
14611[O, D, E, B, A, N]6ADOBEC
15612[O, D, E, B, A, N, C]7ADOBEC
16912[B, A, N, C]4BANC

详细说明:
  1. Iteration 1-5:滑动窗口从 Left=0 开始向右扩展,但字符尚未覆盖 t="ABC" 的所有字符,因此没有有效窗口。
  2. Iteration 6Right=5 时,窗口内字符为 [A, D, O, B, E, C],此时首次找到覆盖 t 的有效窗口,记录最小子串为 "ADOBEC"
  3. Iteration 7-10:随着窗口向右扩展,字符无法继续满足 t 的要求,最小子串保持为 "ADOBEC"
  4. Iteration 11Right=10 时,窗口内字符为 [D, O, B, E, C, O, D, E, B, A],再次满足条件,最小子串仍保持为 "ADOBEC"
  5. Iteration 12:窗口左移到 Left=5,依然保持有效窗口,字符为 [C, O, D, E, B, A],最小子串保持不变。
  6. Iteration 16Right=12 时,窗口内字符为 [B, A, N, C],再次找到有效窗口,更新最小子串为 "BANC"

写在最后

在这篇博客中,我们继续探索了滑动窗口的高级应用,通过对一系列复杂问题的深度剖析,进一步展示了滑动窗口的灵活性与高效性。无论是「水果成篮」的双种类约束,还是「找到字符串中所有字母异位词」的字符频次比较,抑或是「串联所有单词的子串」的字符串匹配与「最小覆盖子串」的字符覆盖问题,这些问题都通过滑动窗口的精妙操作得到了优雅的解决。滑动窗口的核心在于对窗口边界的动态调整和哈希表的巧妙使用,结合不同场景的需求,展现了它在复杂算法挑战中的无限可能性。我们不仅解决了实际问题,更深入理解了滑动窗口的算法思想和设计精髓,为后续的算法学习打下了坚实基础。


以上就是关于【优选算法篇】踏入算法的深邃乐章:滑动窗口的极致探秘的内容啦,各位大佬有什么问题欢迎在评论区指正,或者私信我也是可以的啦,您的支持是我创作的最大动力!❤️

在这里插入图片描述

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

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

相关文章

C for Graphic:径向模糊

最近要做一系列特效需求&#xff0c;顺便记录一下。 径向模糊&#xff08;也叫辐射模糊&#xff09;&#xff1a;一种由内向外发散的模糊的效果 原理&#xff1a;获取中心点&#xff08;centeruv&#xff09;到当前像素&#xff08;pixeluv&#xff09;的朝向法向…

RFC2616 超文本传输协议 HTTP/1.1

一、URL-俗称“网址” HTTP 使用 URL(Uniform Resource Locator&#xff0c;统一资源定位符)来定位资源&#xff0c;它是 URI(Uniform Resource Identifier&#xff0c;统一资源标识符)的子集&#xff0c;URL 在 URI 的基础上增加了定位能力 URI 除了包含 URL&#xff0c;还包…

车载实操:一对一实操学习、CANoe实操学习、推荐就业机会、就业技术支持、协助面试辅导

FOTA模块中OTA的知识点&#xff1a;1.测试过程中发现哪几类问题&#xff1f; 可能就是一个单键的ecu&#xff0c;比如升了一个门的ecu&#xff0c;他的升了之后就关不上&#xff0c;还有就是升级组合ecu的时候&#xff0c;c屏上不显示进度条。 2.在做ota测试的过程中&#xff…

5G NR:UE初始接入信令流程浅介

UE初始接入信令流程 流程说明 用户设备&#xff08;UE&#xff09;向gNB-DU发送RRCSetupRequest消息。gNB-DU 包含 RRC 消息&#xff0c;如果 UE 被接纳&#xff0c;则在 INITIAL UL RRC MESSAGE TRANSFER 消息中包括为 UE 分配的低层配置&#xff0c;并将其传输到 gNB-CU。IN…

PFC和LLC的本质和为什么要用PFC和LLC电路原因

我们可以用电感和电容的特性,以及电压和电流之间的不同步原理来解释PFC(功率因数校正)和LLC(谐振变换器)。 电感和电容的基本概念 电感(Inductor): 电感是一种储存电能的组件。它的电流变化比较慢,电流在电感中延迟,而电压变化得比较快。可以把电感想象成一个“滞后…

『Mysql集群』Mysql高可用集群之主从复制 (一)

Mysql主从复制模式 主从复制有一主一从、主主复制、一主多从、多主一从等多种模式. 我们可以根据它们的优缺点选择适合自身企业情况的主从复制模式进行搭建 . 一主一从 主主复制 (互为主从模式): 实现Mysql多活部署 一主多从: 提高整个集群的读能力 多主一从: 提高整个集群的…

transformers 推理 Qwen2.5 等大模型技术细节详解(一)transformers 初始化和对象加载(文末免费送书)

上周收到一位网友的私信&#xff0c;希望老牛同学写一篇有关使用 transformers 框架推理大模型的技术细节的文章。 老牛同学刚开始以为这类的文章网上应该会有很多&#xff0c;于是想着百度几篇质量稍高一点的回复这位网友。结果&#xff0c;老牛同学搜索后发现&#xff0c;类…

信息与计算科学:“数学 + 计算机”,奏响未来科技新乐章

在当今科技飞速发展的时代&#xff0c;有一个专业如同一颗闪耀的新星&#xff0c;散发着独特的魅力&#xff0c;那就是信息与计算科学专业。 一、专业全貌&#xff1a;追根溯源&#xff0c;领略交叉之美 &#xff08;一&#xff09;专业的诞生与发展 1998 年&#xff0c;教育…

一图解千言,了解常见的流程图类型及其作用

在企业管理、软件研发过程中&#xff0c;经常会需要进行各种业务流程梳理&#xff0c;而流程图就是梳理业务时必要的手段&#xff0c;同时也是梳理的产出。但在不同的情况下适用的流程图又不尽相同。 本文我们就一起来总结一下8 种最常见的流程图类型 数据流程图 数据流程图&…

RHCE——例行性工作

准备工作 [rootlocalhost ~]# cat /etc/yum.repos.d/aliyun.repo [ali-app] nameali-app baseurlhttps://mirrors.aliyun.com/centos-stream/9-stream/AppStream/x86_64/os/ gpgcheck0[ali-base] nameali-base baseurlhttps://mirrors.aliyun.com/centos-stream/9-stream/Base…

JS | JS中类的 prototype 属性和__proto__属性

大多数浏览器的 ES5 实现之中&#xff0c;每一个对象都有__proto__属性&#xff0c;指向对应的构造函数的prototype属性。Class 作为构造函数的语法糖&#xff0c;同时有prototype属性和__proto__属性&#xff0c;因此同时存在两条继承链。 构造函数的子类有prototype属性。‌ …

倍福中控显示屏维修控制面板CP7732-1207-0030

使用的环境条件不当可能会损坏设备。 保护设备&#xff0c;防止灰尘、湿气和热量进入。 使用注意事项&#xff1a; 空气流通不畅 设备安装不正确会阻碍设备内的空气流通&#xff0c;从而导致过热和功能受损。 只能按所示方向将设备安装在相应的壁上。 该设备设计用于安装在…

05 P1157 组合的输出

题目&#xff1a; 代码&#xff1a; #include<iostream> using namespace std; # define M 500 #include<algorithm>int sa[100005],k,n,count1;bool func(int n) {int mark0;if(n1){return 1;}else{for(int i2;i<n-1;i){if(n%i0){mark1;return 0;}}if(mark0)r…

强化学习案例:美团是如何在推荐系统中落地强化学习

目录 美团的强化学习应用场景和分析 场景举例 使用原因 强化学习的六大要素 智能体 环境 行动 奖励 目标 状态 美团强化学习模型设计 美团强化学习工程落地 总体的数据结构关系图 实现步骤 1. 日志收集与实时处理&#xff08;Log Collector, Online Joiner&…

PyTorch 2.5 发布带来一些新特性和改进

官网&#xff1a;https://github.com/pytorch/pytorchGitHub&#xff1a;https://github.com/pytorch/pytorch原文&#xff1a;https://github.com/pytorch/pytorch/releases/tag/v2.5.0 主要亮点 (Highlights)] SDPA CuDNN 后端&#xff1a;为 torch.nn.functional.scaled_d…

C++标准模板库--vector

vector 介绍 vector&#xff08;向量&#xff09;是一种序列容器&#xff0c;表示为可以改变大小的数组。vector中的元素使用连续的存储位置&#xff0c;这意味着也可以使用指向其元素的常规指针偏移量来访问任意元素&#xff0c;且与数组一样高效。但与数组不同的是&#xff…

React Componet类组件详解(老项目)

React类组件是通过创建class继承React.Component来创建的&#xff0c;是React中用于构建用户界面的重要部分。以下是对React类组件的详细解释&#xff1a; 一、定义与基本结构 类组件使用ES6的class语法定义&#xff0c;并继承自React.Component。它们具有更复杂的功能&#…

流量PID控制(开度前馈量计算+辅助PID)

和流体流速(瞬时流量)相关的计算请参考下面文章链接: 1、PLC通过伯努利方程近似计算水箱流量 PLC通过伯努利方程近似计算水箱流量(FC)-CSDN博客文章浏览阅读1.6k次。本文介绍了如何使用PLC通过伯努利方程近似计算水箱中的液体流量,主要涉及流量计算、模型验证、梯形图编程及…

C++学习路线(二十)

项目 模块划分 推箱子游戏 地图初始化 热键控制 推箱子控制 游戏结束 地图初始化 坐标系&#xff08;650&#xff0c;650&#xff09; 地图表示&#xff1a; 使用二维数组 游戏道具展示&#xff08;墙 箱子 箱子目的地 小人 地板&#xff09; 判断游戏…