【算法系列篇】滑动窗口

文章目录
- 前言
- 什么是滑动窗口
- 1.长度最小的子数组
- 1.1 题目要求
- 1.2 做题思路
- 1.3 Java代码实现
- 2.无重复字符的最长子串
- 2.1 题目要求
- 2.2 做题思路
- 2.3 Java代码实现
- 3.最大连续1的个数 III
- 3.1 题目要求
- 3.2 做题思路
- 3.3 Java代码实现
- 4.将x减到0的最小操作数
- 4.1 题目要求
- 4.2 做题思路
- 4.3 Java代码实现
- 5.水果成篮
- 5.1 题目要求
- 5.2 做题思路
- 5.3 Java代码实现
- 6.找到字符串中所有字母异位词
- 6.1 题目要求
- 6.2 做题思路
- 6.3 Java代码实现
- 7.串联所有单词的子串
- 7.1 题目要求
- 7.2 做题思路
- 7.3 Java代码实现
- 8.最小覆盖字串
- 8.1 题目要求
- 8.2 做题思路
- 8.3 Java代码实现
- 总结
前言
前面我们学习了什么是双指针,今天我将为大家分享一种特殊的双指针——滑动窗口,为什么说它是特殊的双指针呢?因为它也是有两个指针维护的,并且两个指针的移动方向是相同的,就跟我们平时生活中的窗口一样,两条边是往相同的方向移动的。
什么是滑动窗口
滑动窗口算法是一种用于解决数组或字符串相关问题的算法。它通过两个指针维护的一个窗口,在窗口内进行操作,并根据问题的要求移动窗口的起始位置或结束位置。
滑动窗口算法通常用于解决需要在连续子数组或子字符串中寻找最大值、最小值、满足特定条件的值等问题。它的基本思想是通过调整窗口的大小和位置,以便在不重复计算的情况下,高效地处理问题。
滑动窗口算法的步骤如下:
- 初始化窗口的起始位置和结束位置。
- 根据问题的要求,移动窗口的起始位置或结束位置。
- 在每次移动窗口时,根据窗口内的元素进行相应的操作,例如计算最大值、最小值、满足特定条件的值等。
- 重复步骤2和步骤3,直到窗口移动到数组或字符串的末尾。
滑动窗口算法的时间复杂度通常为O(n),其中n为数组或字符串的长度。它通过避免重复计算,提高了问题的解决效率。
我们通过几个例子来了解滑动窗口算法。
1.长度最小的子数组
https://leetcode.cn/problems/minimum-size-subarray-sum/
1.1 题目要求
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
提示:
1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105
class Solution {public int minSubArrayLen(int target, int[] nums) {}
}
1.2 做题思路
我们先来看看,如果使用暴力解法该怎么做。分别以每个数字开始,向后找 和>=target的子数组。

暴力解法是通过两层循环,i 从 0开始,j 从 i+1 开始遍历整个数字,找到 和 >= target 的长度最小的子数组。并且这个和是每次循环都从 0 开始加的。
通过观察每次循环找到的长度最小的子数组,我们可以发现,left 指针和 right 指针都是向同一个方向向右移动的,暴力解法是每次循环结束之后 right 的位置就回到 left + 1 的位置,这样就多了很多重复的不必要的计算。所以滑动窗口就是在这个暴力解法的基础上进行优化的,每次 right 的指向不进行返回,而是继续向右滑动,那么为什么 right 的指向可以不用返回呢?因为每次循环 left 的指向都会向右移动一位,而你要想找的长度最小的子数组的和 >= target,你的 right 就必须也是向右移动或者不移动,但是绝对不会是向左移动(在数组元素都是正数的情况下),这种就是滑动窗口的基本特征。
那么知道了使用滑动窗口这个算法的时候,我们来看看具体应该如何实现。定义一个 sum 变量,存储每次进窗口之后这个窗口元素的和,并且这个sum 不是每一次都是逐个累加而是用之前的 sum 加上进窗口的这个元素,当 sum >= target 的时候,就需要进行出窗口的操作,并且在出窗口的时候,还需要判断是否需要更新 ret 的值,继续寻找后面的长度最小的子数组,每出一个元素,sum 就需要减去这个出去的数,出窗口一直出到 sum < target,然后再进窗口,反复上面的操作,直到 right 到达数组末尾。

1.3 Java代码实现
class Solution {public int minSubArrayLen(int target, int[] nums) {int ret = Integer.MAX_VALUE;for(int left = 0,right = 0, sum = 0; right < nums.length; right++) {sum += nums[right];while(sum >= target) {ret = Math.min(ret,right - left + 1);sum -= nums[left++];}}return ret == Integer.MAX_VALUE ? 0 : ret;}
}

2.无重复字符的最长子串
https://leetcode.cn/problems/longest-substring-without-repeating-characters/
2.1 题目要求
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
class Solution {public int lengthOfLongestSubstring(String s) {}
}
2.2 做题思路
先来看看暴力解法如何解决

通过暴力解法,我们也可以发现,每次循环找到的无重复字符的最长子串它的 left 的 right 都是向右移动的,所以这个题目同样使用滑动窗口来解决。
因为这里求的是长度最长的无重复字符的子串,所以需要在进窗口的时候进行判断是否需要更新最大长度,而判断是否有重复的字符,我们可以借助哈希表来进行判断。

2.3 Java代码实现
class Solution {public int lengthOfLongestSubstring(String ss) {char[] s = ss.toCharArray();int[] hash = new int[128];int ret = 0;for(int left = 0, right = 0; right < s.length; right++) {char in = s[right];hash[in]++;if(hash[in] == 1) {ret = Math.max(ret,right - left + 1);}while(hash[in] > 1) {char out = s[left++];hash[out]--;}}return ret;}
}

3.最大连续1的个数 III
https://leetcode.cn/problems/max-consecutive-ones-iii/
3.1 题目要求
给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。
示例 1:
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。
示例 2:
输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。
提示:
1 <= nums.length <= 105
nums[i] 不是 0 就是 1
0 <= k <= nums.length
class Solution {public int longestOnes(int[] nums, int k) {}
}
3.2 做题思路
很多人看到这个翻转0不知道啥意思,说通俗点就是0可以变成1,同样,先来看看暴力解法如何解决。

left 指针和 right 指针都是向右方向移动的,所以这道题目同样使用滑动窗口来解决。我们的判断条件是以窗口内0的数量为判断条件,并且求的是最大长度,所以是在进窗口的时候进行判断。

3.3 Java代码实现
class Solution {public int longestOnes(int[] nums, int k) {int ret = 0;for(int left = 0, right = 0,count = 0; right < nums.length; right++) {if(nums[right] == 0) count++;if(count <= k) {ret = Math.max(ret,right - left + 1);}while(count > k) {if(nums[left++] == 0) count--;}}return ret;}
}

4.将x减到0的最小操作数
https://leetcode.cn/problems/minimum-operations-to-reduce-x-to-zero/
4.1 题目要求
给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。
示例 1:
输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:最佳解决方案是移除后两个元素,将 x 减到 0 。
示例 2:
输入:nums = [5,6,7,8,9], x = 4
输出:-1
示例 3:
输入:nums = [3,2,20,1,1,3], x = 10
输出:5
解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 104
1 <= x <= 109
class Solution {public int minOperations(int[] nums, int x) {}
}
4.2 做题思路
这道题目的意思就是:给定一个数字x,每次从数组的最左边或者最右边选择一个数减去,然后使x减到0的最少的操作数。这道题目如果从正面去做的话,会先的非常麻烦,不妨我们换一条思路,他求的是数组两边减去的最少的数字,不妨我们就求数组中间最长的子数组,使它们的和为数组所有元素的总和减去 target ,这样就能是数组的两侧的和为 target 并且长度最短。所以这个题目就跟前面的求数组长度最长的子数组是差不多的,就只是判断的地方不同,这里需要在出窗口之后判断是否需要更新ret的值,这里我就不给大家过多介绍了,关键就是能够知道这个思路。
4.3 Java代码实现
class Solution {public int minOperations(int[] nums, int x) {int sum = 0;for(int n : nums) sum += n; //求数组所有元素的总和int target = sum - x;if(target < 0) return -1;int ret = -1;for(int left = 0, right = 0,sum1 = 0; right < nums.length; right++) {sum1 += nums[right];while(sum1 > target) {sum1 -= nums[left++];}if(sum1 == target) {ret = Math.max(ret,right - left + 1);}}return ret == -1 ? -1 : nums.length - ret;}
}

5.水果成篮
https://leetcode.cn/problems/fruit-into-baskets/
5.1 题目要求
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。
你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:
- 你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
- 你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当* 符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
- 一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。
给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。
示例 1:
输入:fruits = [1,2,1]
输出:3
解释:可以采摘全部 3 棵树。
示例 2:
输入:fruits = [0,1,2,2]
输出:3
解释:可以采摘 [1,2,2] 这三棵树。
如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。
示例 3:
输入:fruits = [1,2,3,2,2]
输出:4
解释:可以采摘 [2,3,2,2] 这四棵树。
如果从第一棵树开始采摘,则只能采摘 [1,2] 这两棵树。
示例 4:
输入: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
class Solution {public int totalFruit(int[] fruits) {}
}
5.2 做题思路
根据题目我们可以知道,只有两个篮子,只能装两种水果,并且每个篮子可以装的水果数是无限的,这道题跟子数组的问题是类似的,只是判断条件变成了水果的种类,进窗口的时候,添加水果的种类很简单,当这个种类的水果数量在之前为0时,就说明是一个新的种类,但是当我们出窗口的时候,如果某一种类的水果数量减为0的时候,就需要减去一种种类,那么我们如何统计某一水果的数量呢?哈希表,使用哈希表可以很高效的对某一种类的数量进行统计。
5.3 Java代码实现
class Solution {public int totalFruit(int[] fruits) {int ret = 1;int[] hash = new int[fruits.length];for(int left = 0, right = 0,kinds = 0; right < fruits.length; right++) {int in = fruits[right];if(hash[in]++ == 0) kinds++;if(kinds <= 2) { //当水果的种类小于等于2的时候就需要做出判断ret = Math.max(ret,right - left + 1);}while(kinds > 2) {int out = fruits[left++];if(--hash[out] == 0) kinds--;}}return ret;}
}

6.找到字符串中所有字母异位词
https://leetcode.cn/problems/find-all-anagrams-in-a-string/
6.1 题目要求
给定两个字符串 s 和 p,找到 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 * 104
s 和 p 仅包含小写字母
class Solution {public List<Integer> findAnagrams(String s, String p) {}
}
6.2 做题思路
这道题其实就相当于使用一个大小为 p 字符串长度的框从 s 字符串头部开始框 p 字符串长度的字符串,然后判断框起来的字符串是否是 p 字符串的异位词。
窗口中的大小是确定的,最终的窗口的大小是p字符串的长度,也就是说我们的判断条件就是窗口内的字符串是否是p字符串的异位词,这也是解决这道题的关键。那么我们应该如何解决呢?同样是使用两个哈希表,第一个哈希表统计p字符串每个单词出现的次数,当进窗口的时候,第二个哈希表中该字符出现的次数就加一,并且如果将这个字符添加进哈希表之后,该哈希表中对应字符出现的次数小于等于第一个哈希表对应字符出现的次数,就说明进窗口的这个字符为有效字符,我们使用 count 来记录有效字符的个数,count++,当 count 等于 p 字符串的长度时,就需要更新结果:将 left 的坐标添加进列表中。
6.3 Java代码实现
class Solution {public List<Integer> findAnagrams(String ss, String pp) {List<Integer> list = new ArrayList<>();char[] s = ss.toCharArray();char[] p = pp.toCharArray();int[] hash1 = new int[26];int[] hash2 = new int[26];for(char ch : p) hash1[ch - 'a']++;int len = p.length;for(int left = 0, right = 0,count = 0; right < s.length; right++) {char in = s[right];if(++hash2[in - 'a'] <= hash1[in - 'a']) count++;if(right - left + 1 > len) {char out = s[left++];if(hash2[out - 'a']-- <= hash1[out - 'a']) count--;}if(count == len) {list.add(left);}}return list;}
}

7.串联所有单词的子串
https://leetcode.cn/problems/substring-with-concatenation-of-all-words/
7.1 题目要求
给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。
s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。
- 例如,如果 words = [“ab”,“cd”,“ef”], 那么 “abcdef”, “abefcd”,“cdabef”, “cdefab”,“efabcd”, 和 “efcdab” 都是串联子串。 “acdbef” 不是串联子串,因为他不是任何 words 排列的连接。
返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。
示例 1:
输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。
子串 "barfoo" 开始位置是 0。它是 words 中以 ["bar","foo"] 顺序排列的连接。
子串 "foobar" 开始位置是 9。它是 words 中以 ["foo","bar"] 顺序排列的连接。
输出顺序无关紧要。返回 [9,0] 也是可以的。
示例 2:
输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
输出:[]
解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。
s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。
所以我们返回一个空数组。
示例 3:
输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]
输出:[6,9,12]
解释:因为 words.length == 3 并且 words[i].length == 3,所以串联子串的长度必须为 9。
子串 "foobarthe" 开始位置是 6。它是 words 中以 ["foo","bar","the"] 顺序排列的连接。
子串 "barthefoo" 开始位置是 9。它是 words 中以 ["bar","the","foo"] 顺序排列的连接。
子串 "thefoobar" 开始位置是 12。它是 words 中以 ["the","foo","bar"] 顺序排列的连接。
提示:
1 <= s.length <= 104
1 <= words.length <= 5000
1 <= words[i].length <= 30
words[i] 和 s 由小写英文字母组成
class Solution {public List<Integer> findSubstring(String s, String[] words) {}
}
7.2 做题思路
这道题目跟上面的一个题目是类似的,只是这里将字母换成了单词,所以我们可以仿照上面一个题的思路,将words数组中的每个字符串当作一个字母,s 字符串每与words数组中每个单词相同长度的字符串作为一个字母。

因为不仅可以从 b 开始,将字符数组分为多个字符串,还可以从a和r开始,所以这里我们需要进行 words 数组中每个单词长度的循环次数的操作。
这里的哈希表用数组就不容易模拟了,所以这里就需要用到 HashMap
7.3 Java代码实现
class Solution {public List<Integer> findSubstring(String s, String[] words) {List<Integer> list = new ArrayList<>();Map<String,Integer> map1 = new HashMap<>();for(String tmp : words) {map1.put(tmp,map1.getOrDefault(tmp,0) + 1);}int len = words.length; //求words数组的大小int m = words[0].length(); //求words数组中每个单词的长度for(int i = 0; i < m; i++) {Map<String,Integer> map2 = new HashMap<>();for(int left = i, right = i, count = 0; right <= s.length()-m; right += m) {String in = s.substring(right,right + m);map2.put(in,map2.getOrDefault(in,0) + 1);if(map2.get(in) <= map1.getOrDefault(in,0)) count++;if(right - left + 1 > len * m) {String out = s.substring(left,left + m);if(map2.get(out) <= map1.getOrDefault(out,0)) count--;map2.put(out,map2.get(out) - 1);left += m;}if(count == len) list.add(left);}}return list;}
}

8.最小覆盖字串
https://leetcode.cn/problems/minimum-window-substring/
8.1 题目要求
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 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 的子串中,
因此没有符合条件的子字符串,返回空字符串。
提示:
m == s.length
n == t.length
1 <= m, n <= 105
s 和 t 由英文字母组成
class Solution {public String minWindow(String s, String t) {}
}
8.2 做题思路
因为这道题目中说了,可以出现重复的字符,所以这道题的判断条件就是窗口中是否含有 t 字符串中的所有字符,并且窗口中的每个字符出现的次数必须大于 t 字符串中每个字符出现的次数。那么这道题的步骤主要分为两步:
- 在s字符串中,找到含有 t 字符串中含有的所有字符的窗口
- 在这个窗口中找长度最小的子串

8.3 Java代码实现
class Solution {public String minWindow(String ss, String tt) {char[] s = ss.toCharArray();char[] t = tt.toCharArray();int[] hash1 = new int[128];int[] hash2 = new int[128];int kinds = 0;for(char ch : t) {if(hash1[ch]++ == 0) kinds++;}int begin = -1;int minLen = Integer.MAX_VALUE;for(int left = 0, right = 0,count = 0; right < s.length; right++) {char in = s[right];if(++hash2[in] == hash1[in]) count++;while(count == kinds) {if(right - left + 1 < minLen) {begin = left;minLen = right - left + 1;}char out = s[left++];if(hash2[out]-- == hash1[out]) count--;}}if(begin == -1) return new String();else return ss.substring(begin,begin + minLen);}
}

总结
当涉及到解决子串或子数组的问题时,滑动窗口算法是一种非常有效的技术。它通过维护一个窗口,该窗口在字符串或数组上滑动,以解决特定问题。
滑动窗口算法的主要思想是使用两个指针,一个指向窗口的起始位置,另一个指向窗口的结束位置。通过调整这两个指针,可以扩展或收缩窗口,以找到所需的解。算法的关键是确定窗口的移动规则以及如何在移动过程中更新解。
下面是滑动窗口算法的一般步骤:
- 初始化窗口的起始指针和结束指针,使其指向合理的位置。
- 进入一个循环,不断尝试扩展窗口,直到窗口无法再扩展为止。
- 在每次窗口移动时,更新解(如果有必要)。
- 如果窗口仍然满足问题的要求,尝试收缩窗口,以寻找更优的解。
- 重复步骤3和4,直到窗口完全收缩并处理完所有元素。
滑动窗口算法的优点是其时间复杂度通常是线性的,因为它避免了对每个子串或子数组的重复计算,节约了计算资源。它也通常可以在O(1)的空间复杂度下完成。
滑动窗口算法常用于解决一些经典问题,例如字符串匹配、子数组和子串求和、最长/最短子数组等。通过适当定义窗口的移动规则和解的更新方式,可以针对不同的具体问题进行定制化的实现。
总结而言,滑动窗口算法是一种高效的解决子串或子数组问题的方法。它的核心思想是通过维护一个窗口,在问题的限定条件下移动窗口的起始和结束指针,同时利用解的特性来优化计算过程。使用滑动窗口算法可以提高问题的解决效率,并减少不必要的计算。
相关文章:
【算法系列篇】滑动窗口
文章目录 前言什么是滑动窗口1.长度最小的子数组1.1 题目要求1.2 做题思路 1.3 Java代码实现2.无重复字符的最长子串2.1 题目要求2.2 做题思路2.3 Java代码实现 3.最大连续1的个数 III3.1 题目要求3.2 做题思路3.3 Java代码实现 4.将x减到0的最小操作数4.1 题目要求4.2 做题思路…...
多维时序 | MATLAB实现BiTCN-BiGRU-Attention多变量时间序列预测
多维时序 | MATLAB实现SABO-CNN-GRU-Attention多变量时间序列预测 目录 多维时序 | MATLAB实现SABO-CNN-GRU-Attention多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | MATLAB实现BiTCN-BiGRU-Attention多变量时间序列预测。 模型描…...
Docker容器与虚拟化技术:Docker compose部署LNMP
目录 一、理论 1.LNMP架构 2.背景 3.Dockerfile部署LNMP 3.准备Nginx镜像 4.准备MySQL容器 5.准备PHP镜像 6.上传wordpress软件包 7.编写docker-compose.yml 8.构建与运行docker-compose 9.启动 wordpress 服务 10.浏览器访问 11.将运行中的 docker容器保存为 doc…...
高性能服务器Nodejs操作Mysql数据库
目录 1 Node 操作 mysql1.2 操作 mysql 数据库 2 Web 开发模式2.1 服务端渲染2.2 前后端分离2.3 如何选择 3 身份认证3.1 Session 认证机制3.2 JWT 认证机制 1 Node 操作 mysql 数据库和身份认证 配置 mysql 模块 安装 mysql 模块 npm install mysql建立连接 const mysql …...
ffmpeg将rtsp流转成mp4
命令行版本 ffmpeg -y -i "rtsp://你的rtsp地址" -vcodec copy -f mp4 d:/1.mp4中间的rtsp网址一定要加上双引号,避免出现url有特殊字符的问题 java代码版本 如果不支持tcp协议,去掉下面两个参数即可,加上这两个参数是因为ffmpeg默认使用ud…...
第十四天|层序遍历、226.翻转二叉树 (优先掌握递归)、101. 对称二叉树 (优先掌握递归)
层序遍历 题目链接:102. 二叉树的层序遍历 - 力扣(LeetCode) /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(n…...
如何使用装rancher安装k8s集群(k8s集群图形化管理工具)
前言 kubernetes集群的图形化管理工具主要有以下几种: 1、 Kubernetes Dashborad: Kubernetes 官方提供的图形化工具 2、 Rancher: 目前比较主流的企业级kubernetes可视化管理工具 3、各个云厂商Kubernetes集成的管理器 4、 Kuboard: 国产开源Kubernetes可视化管理…...
类加载器与双亲委派
类加载器与双亲委派 Java 类加载器(Class Loader)是 Java 虚拟机(JVM)的一部分,负责将类的字节码加载到内存中,并将其转换为可执行的 Java 对象。类加载器在 Java 应用程序中起着重要的作用,它…...
用Python创造乐趣:编写你自己的探索游戏世界
在当今数字化时代,编程不再是一个专业程序员的专利。无论你是一个编程新手还是有一定经验的开发者,用Python编写简单的游戏是一个有趣且富有创造性的方式。在这篇博客中,我们将探索如何用Python构建一个基本的探索游戏世界,让玩家…...
git stash弹出栈中的指定内容
使用 git stash 的相关命令来选择性地弹出特定的 stash 内容,应用到指定的分支上。如果我们使用 git stash 命令已经存储了多个记录时,每个 stash 记录都会有一个唯一的标识符(stash{0}、stash{1}…)。通过这些标识符可以应用或弹…...
5.7 汇编语言:汇编高效乘法运算
乘法指令是一种在CPU中实现的基本算术操作,用于计算两个数的乘积。在汇编语言中,乘法指令通常是通过mul(无符号乘法)和imul(有符号乘法)这两个指令实现的。由于乘法指令在执行时所消耗的时钟周期较多&#…...
Graphql中的N+1问题
开篇 原文出处 Graphql 是一种 API 查询语言和运行时环境,可以帮助开发人员快速构建可伸缩的 API。然而,尽管 Graphql 可以提供一些优秀的查询性能和数据获取的能力,但是在使用 Graphql 的过程中,开发人员也会遇到一些常见问题&…...
mysql、oracle、sqlserver常见方法区分
整理了包括字符串与日期互转、字符串与数字互转、多行合并为一行、拼接字段等一些常用的函数,当然有些功能实现的方法不止一种,这里列举了部分常用的,后续会持续补充。 MySQLOracleSQL Server字符串转数字 CAST(123 as SIGNED) 或 CONVERT(12…...
AcWing 4382. 快速打字
原题链接:AcWing 4382. 快速打字 关键词:双指针、判断子序列 芭芭拉是一个速度打字员。 为了检查她的打字速度,她进行了一个速度测试。 测试内容是给定她一个字符串 I,她需要将字符串正确打出。 但是,芭芭拉作为一…...
DataFrame.query()--Pandas
1. 函数功能 Pandas 中的一个函数,用于在 DataFrame 中执行查询操作。这个方法会返回一个新的 DataFrame,其中包含符合查询条件的数据行。请注意,query 方法只能用于筛选行,而不能用于筛选列。 2. 函数语法 DataFrame.query(ex…...
【C语言】美元名字和面额对应问题
题目 美元硬币从小到大分为1美分(penny)5美分(nickel)10美分(dime)25美分(quarter)和50美分(half-dollar),写一个程序实现当给出一个数字面额可以…...
uniapp隐藏底部导航栏(非自定义底部导航栏)
uniapp隐藏底部导航栏 看什么看,要多看uni官方文档,里面啥都有 看什么看,要多看uni官方文档,里面啥都有 uniapp官方网址:uni设置TabBar // 展示 uni.showTabBar({animation:true,success() {console.debug(隐藏成功)…...
CSS background 背景
background属性为元素添加背景效果。 它是以下属性的简写,按顺序为: background-colorbackground-imagebackground-repeatbackground-attachmentbackground-position 以下所有示例中的花花.jpg图片的大小是4848。 1 background-color background-col…...
安防监控视频平台EasyCVR视频汇聚平台和税务可视化综合管理应用方案
一、方案概述 为了确保税务执法的规范性和高效性,国家税务总局要求全面推行税务系统的行政执法公示制度、执法全过程记录制度和重大执法决定法制审核制度。为此,需要全面推行执法全过程记录制度,并推进信息化建设,实现执法全过程的…...
深度学习实战50-构建ChatOCR项目:基于大语言模型的OCR识别问答系统实战
大家好,我是微学AI,今天给大家介绍一下深度学习实战50-构建ChatOCR项目:基于大语言模型的OCR识别问答系统实战,该项目是一个基于深度学习和大语言模型的OCR识别问答系统的实战项目。该项目旨在利用深度学习技术和先进的大语言模型,构建一个能够识别图像中文本,并能够回答与…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
